UNPKG

crocks

Version:

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

124 lines (96 loc) 3.19 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('Arrow') var _type = require('../core/types').typeFn(type(), VERSION) var fl = require('../core/flNames') var isFunction = require('../core/isFunction') var isSameType = require('../core/isSameType') var Pair = require('../core/types').proxy('Pair') var _id = function () { return Arrow(function (x) { return x; }); } function Arrow(runWith) { var obj; if(!isFunction(runWith)) { throw new TypeError('Arrow: Function required') } var inspect = function () { return ("Arrow" + (_inspect(runWith))); } var id = _id var _map = function (fn) { return Arrow(function (x) { return fn(runWith(x)); }); } function compose(method) { return function(m) { if(!isSameType(Arrow, m)) { throw new TypeError(("Arrow." + method + ": Arrow required")) } return _map(m.runWith) } } function map(method) { return function(fn) { if(!isFunction(fn)) { throw new TypeError(("Arrow." + method + ": Function required")) } return _map(fn) } } function contramap(method) { return function(fn) { if(!isFunction(fn)) { throw new TypeError(("Arrow." + method + ": Function required")) } return Arrow(function (x) { return runWith(fn(x)); }) } } function promap(method) { return function(l, r) { if(!isFunction(l) || !isFunction(r)) { throw new TypeError(("Arrow." + method + ": Functions required for both arguments")) } return Arrow(function (x) { return r(runWith(l(x))); }) } } function first() { return Arrow(function(x) { if(!isSameType(Pair, x)) { throw TypeError('Arrow.first: Pair required for inner argument') } return x.bimap(runWith, function (x) { return x; }) }) } function second() { return Arrow(function(x) { if(!isSameType(Pair, x)) { throw TypeError('Arrow.second: Pair required for inner argument') } return x.bimap(function (x) { return x; }, runWith) }) } function both() { return Arrow(function(x) { if(!isSameType(Pair, x)) { throw TypeError('Arrow.both: Pair required for inner argument') } return x.bimap(runWith, runWith) }) } return ( obj = { inspect: inspect, toString: inspect, type: type, runWith: runWith, id: id, first: first, second: second, both: both, compose: compose('compose'), map: map('map'), contramap: contramap('contramap'), promap: promap('promap') }, obj[fl.id] = id, obj[fl.compose] = compose(fl.compose), obj[fl.map] = map(fl.map), obj[fl.contramap] = contramap(fl.contramap), obj[fl.promap] = promap(fl.promap), obj['@@type'] = _type, obj.constructor = Arrow, obj ) } Arrow.id = _id Arrow.type = type Arrow[fl.id] = _id Arrow['@@type'] = _type Arrow['@@implements'] = _implements( [ 'compose', 'contramap', 'id', 'map', 'promap' ] ) module.exports = Arrow