UNPKG

fp-ts-std

Version:

The missing pseudo-standard library for fp-ts.

54 lines (53 loc) 2.32 kB
import * as O from "fp-ts/Option"; import { constant, flow, pipe } from "fp-ts/function"; import * as NEA from "fp-ts/NonEmptyArray"; import { unsafeExpect as unsafeExpectO } from "./Option"; import * as A from "fp-ts/Array"; import * as Map from "fp-ts/Map"; import * as Semigroup from "fp-ts/Semigroup"; import * as L from "./Lazy"; import { add, decrement, increment } from "./Number"; import { dup, toFst, toSnd } from "./Tuple"; const unfoldDup = (f) => (x) => A.unfold(x, flow(f, O.map(dup))); const unfoldDup1 = (f) => (x) => pipe(unfoldDup(f)(x), A.prepend(x)); export const fromTo = (E) => (start) => fromThenTo(E)(start)(pipe(E.succ(start), O.getOrElse(constant(start)))); export const fromThenTo = (E) => (first) => (second) => (limit) => { const start = E.fromEnum(first); const step = E.fromEnum(second) - start; const end = E.fromEnum(limit); if (step < 1 || end < start) return NEA.of(first); const f = flow(O.fromPredicate(n => n <= end), O.map(toSnd(add(step)))); return pipe(A.unfold(start, f), A.filterMap(E.toEnum), xs => xs); }; export const upFromExcl = (E) => unfoldDup(E.succ); export const upFromIncl = (E) => unfoldDup1(E.succ); export const downFromExcl = (E) => unfoldDup(E.pred); export const downFromIncl = (E) => unfoldDup1(E.pred); export const defaultCardinality = (E) => { const f = (n) => flow(E.succ, O.match(constant(n), x => f(n + 1)(x))); return f(1)(E.bottom); }; export const universe = (E) => fromTo(E)(E.bottom)(E.top); export const inverseMap = (E) => (Eq) => (f) => { const ys = pipe(universe(E), NEA.map(toFst(f)), Map.fromFoldable(Eq, Semigroup.last(), NEA.Foldable)); return x => Map.lookup(Eq)(x)(ys); }; export const getUnsafeConstantEnum = (Ord) => (xs) => { const f = (y) => pipe(xs, A.findIndex(z => Ord.equals(y, z))); const g = (n) => A.lookup(n)(xs); const sorted = NEA.sort(Ord)(xs); const Bounded = { ...Ord, top: NEA.last(sorted), bottom: NEA.head(sorted), }; return { ...Bounded, succ: flow(f, O.chain(flow(increment, g))), pred: flow(f, O.chain(flow(decrement, g))), toEnum: g, fromEnum: flow(f, unsafeExpectO("Failed to lookup fromEnum input via getUnsafeConstantEnum")), cardinality: L.of(xs.length), }; };