code: function filter(collection, fn, ctx) {
    const [col, func] = isFunction(collection) ? [null, collection.bind(fn)] : [collection, fn.bind(ctx)];
    return col ? sequence(col, filter(func)) : xform => filterTransducer(func, xform);
  }
docs: **Creates a collection containing only the elements from the input collection that pass a predicate function.**
  
  The elements are not in any way modified. Quite simply, if the predicate returns `true` for an element, it's included
  in the output collection, and if it returns `false`, that element is not included.
  
  If no collection is provided, a function is returned that can be passed to `{@link module:xduce.sequence|sequence}`,
  et al.
  
  ```
  const even = x => x % 2 === 0; *
  const result = filter([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], even);
  // result = [2, 4, 6, 8, 10]
  ```
  
  @memberof module:xduce.transducers
  
  @param {*} [collection] An optional input collection that is to be transduced.
  @param {function} fn A predicate function. This takes each element of the input collection and returns `true` or
  `false` based on that element. Each that returns `true` will be included in the output collection.
  @param {object} [ctx] An optional context object which is set to `this` for the function `fn`. This does not work if
  `fn` is an arrow function, as they cannot be bound to contexts.
  @return {(*|module:xduce~transducerFunction)} If a collection is supplied, then the function returns a new
  collection of the same type containing only the elements that pass the predicate function. If no collection is
  supplied, a transducer function, suitable for passing to `{@link module:xduce.sequence|sequence}`,
  `{@link module:xduce.into|into}`, etc. is returned.