MaybeApply

node v8.17.0
version: 5.0.0
endpointsharetweet
const util = require("util") const { Obj, Arr, Fn, implement, Functor, Apply } = require("@masaeedu/fp") const { adt } = require("@masaeedu/adt") // :: type Apply f = { lift2: (a -> b -> c) -> f a -> f b -> f c } // :: type Applicative f = { of: a -> f a } & (Apply f) // :: type Either l r = { label: "Left", values: '[l] } | { label: "Right", values: '[r] } // :: { // :: Left: a -> Either a b, // :: Right: b -> Either a b, // :: match: { Left: a -> c, Right: b -> c } -> Either a b -> c // :: } const Either = adt({ Left: ["a"], Right: ["b"] }) const { Left, Right, match } = Either // :: type MaybeApply f a = Either (f a) a // :: Apply f -> Applicative (MaybeApply f) const MaybeApply = A => { const of = Right const lift2 = f => match({ Left: ax => match({ Left: ay => Left(A.lift2(f)(ax)(ay)), Right: y => Left(A.map(x => f(x)(y))(ax)) }), Right: x => match({ Left: ay => Left(A.map(y => f(x)(y))(ay)), Right: y => Right(f(x)(y)) }) }) return Fn.flip(Fn.pipe)({ of, lift2 })([ implement(Apply), implement(Functor), implement(Apply) ]) } // Obj only implements Apply, not Applicative, so for example Obj.of is undefined console.log(Obj.of) // However, MaybeApply(Obj) is an applicative console.log(MaybeApply(Obj).of) // This means we can sequence arrays of objects by simply promoting them // :: (StrMap String)[] const input = [{ foo: "hello", bar: "hello" }, { foo: "world", bar: "world" }] // :: Applicative (MaybeApply StrMap) const A = MaybeApply(Obj) // :: Either (StrMap String[]) String[] const result = Arr.traverse(A)(Left)(input) const log = x => console.log(util.inspect(x, { depth: null })) log(match({ Left: x => x, Right: x => x })(result)) // { foo: [ 'hello', 'world' ], bar: [ 'hello', 'world' ] }
Loading…

no comments

    sign in to comment