UNPKG

crocks

Version:

A collection of well known Algebraic Datatypes for your utter enjoyment.

108 lines (81 loc) 2.51 kB
/** @license ISC License (c) copyright 2016 original and current authors */ /** @author Ian Hofmann-Hicks (evil) */ var VERSION = 2 var _implements = require('../core/implements') var _inspect = require('../core/inspect') var type = require('../core/types').type('Reader') var _type = require('../core/types').typeFn(type(), VERSION) var fl = require('../core/flNames') var compose = require('../core/compose') var isFunction = require('../core/isFunction') var isSameType = require('../core/isSameType') var _of = function (x) { return Reader(function () { return x; }); } function ask(fn) { if(!arguments.length) { return Reader(function (x) { return x; }) } if(isFunction(fn)) { return Reader(fn) } throw new TypeError('Reader.ask: No argument or function required') } function Reader(runWith) { var obj; if(!arguments.length || !isFunction(runWith)) { throw new TypeError('Reader: Must wrap a function') } var of = _of var inspect = function () { return ("Reader" + (_inspect(runWith))); } function map(method) { return function(fn) { if(!isFunction(fn)) { throw new TypeError(("Reader." + method + ": Function required")) } return Reader(compose(fn, runWith)) } } function ap(m) { if(!isSameType(Reader, m)) { throw new TypeError('Reader.ap: Reader required') } return Reader(function(e) { var fn = runWith(e) if(!isFunction(fn)) { throw new TypeError('Reader.ap: Wrapped function must return a function') } return m.map(fn).runWith(e) }) } function chain(method) { return function(fn) { if(!isFunction(fn)) { throw new TypeError(("Reader." + method + ": Function required")) } return Reader(function(e) { var m = fn(runWith(e)) if(!isSameType(Reader, m)) { throw new TypeError(("Reader." + method + ": Function must return a Reader")) } return m.runWith(e) }) } } return ( obj = { inspect: inspect, toString: inspect, runWith: runWith, type: type, ap: ap, of: of, map: map('map'), chain: chain('chain') }, obj[fl.of] = of, obj[fl.map] = map(fl.map), obj[fl.chain] = chain(fl.chain), obj['@@type'] = _type, obj.constructor = Reader, obj ) } Reader.of = _of Reader.ask = ask Reader.type = type Reader[fl.of] = _of Reader['@@type'] = _type Reader['@@implements'] = _implements( [ 'ap', 'chain', 'map', 'of' ] ) module.exports = Reader