crocks
Version:
A collection of well known Algebraic Datatypes for your utter enjoyment.
108 lines (81 loc) • 2.51 kB
JavaScript
/** @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