crocks
Version:
A collection of well known Algebraic Datatypes for your utter enjoyment.
124 lines (96 loc) • 3.19 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('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