UNPKG

monad-state

Version:
95 lines (85 loc) 2.09 kB
/** * * @module monad-state */ ;(() => { 'use strict' const { inputs } = require('guarded') const { ap, map: omap } = require('fun-object') const { any, fun, tuple } = require('fun-type') const curry = require('fun-curry') /** * * of :: a -> Seed -> [a, Seed] * * @function module:monad-state.of * * @param {*} a - anything * @param {*} s - state * * @return {Array} [a, s] */ const of = (a, s) => [a, s] /** * * map :: (a -> b) -> (s -> [a, s]) -> s -> [b, s] * * @function module:monad-state.map * * @param {Function} a2b - a -> b * @param {Function} sa - s -> [a, s] * @param {*} s - state * * @return {Array} [b, s] */ const map = (a2b, sa, s) => chain(sa, (a, s1) => of(a2b(a), s1), s) /** * * chain :: (s -> [a, s]) -> (a -> s -> [b, s]) -> s -> [b, s] * * @function module:monad-state.chain * * @param {Function} sa - s -> [a, s] * @param {Function} a2sb - a -> s -> [b, s] * @param {*} s0 - state * * @return {Array} [b, s] */ const chain = (sa, a2sb, s0) => (([a, s1]) => a2sb(a, s1))(sa(s0)) /** * * liftM2 :: ((a, b) -> c) -> (s -> [a, s]) -> (s -> [b, s]) -> s -> [c, s] * * @function module:monad-state.liftM2 * * @param {Function} ab2c - (a, b) -> c * @param {Function} sa - s -> [a, s] * @param {Function} sb - s -> [b, s] * @param {*} s0 - state * * @return {Array} [c, s] */ const liftM2 = (ab2c, sa, sb, s0) => chain(sa, (a1, s1) => map(b1 => ab2c(a1, b1), sb, s1), s0) /** * * run :: s -> (s -> [a, s]) -> a * * @function module:monad-state.run * * @param {*} s - state * @param {Function} sa - s -> [a, s] * * @return {*} a */ const run = (s, sa) => sa(s)[0] const api = { of, map, chain, liftM2, run } const guards = omap(inputs, { of: tuple([any, any]), map: tuple([fun, fun, any]), chain: tuple([fun, fun, any]), liftM2: tuple([fun, fun, fun, any]), run: tuple([any, fun]) }) module.exports = omap(curry, ap(guards, api)) })()