UNPKG

@fpjs/overture

Version:
49 lines (40 loc) 1.59 kB
// 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));