@fpjs/overture
Version:
A Javascript prelude
49 lines (40 loc) • 1.59 kB
JavaScript
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/**
* Foldable provides a generalization of folding operations to arbitrary data
* structures.
*/
import {compose, not, type} from "@fpjs/overture/base";
import {pure} from "@fpjs/overture/algebras/applicative";
import {empty, concat} from "@fpjs/overture/algebras/monoid";
///:: a -> boolean
export const isFoldable = (x) => "fantasy-land/reduce" in x;
///:: Foldable t => (b -> a -> b) -> b -> t a -> b
export const foldl = (f) => (z) => (x) => {
const op = x["fantasy-land/reduce"];
if (op === undefined) {
throw TypeError(`'${type(x)}' is not Foldable.`);
}
return op.call(x, (y, x) => f (y) (x), z);
};
export const reduce = foldl;
/**
* Map every element of the structure to a monoid, and combine them.
*/
///:: (Foldable t, Monoid m) => TypeRep m => (a -> m) -> t a -> m
export const foldMap = (T) => (f) => foldl (
(acc) => (x) => concat (acc) (f (x))
) (empty (T));
/**
* Filter elements matching the predicate.
*/
///:: (Foldable t, Applicative t, Monoid (t a)) =>
/// TypeRep (t a) -> (a -> boolean) -> t a -> t a
export const filter = (T) => (p) => foldMap (T) (
(x) => p (x) ? pure (T) (x) : empty (T)
);
/** Filter with the reverse predicate */
///:: (Foldable t, Applicative t, Monoid (t a)) =>
/// TypeRep (t a) -> (a -> boolean) -> t a -> t a -> t a
export const filterOut = (T) => (p) => filter (T) (compose (not) (p));