crocks
Version:
A collection of well known Algebraic Datatypes for your utter enjoyment.
149 lines (114 loc) • 3.74 kB
JavaScript
/** @license ISC License (c) copyright 2016 original and current authors */
/** @author Ian Hofmann-Hicks (evil) */
var VERSION = 3
var _equals = require('../core/equals')
var _implements = require('../core/implements')
var _innerConcat = require('../core/innerConcat')
var _inspect = require('../core/inspect')
var type = require('../core/types').type('Identity')
var _type = require('../core/types').typeFn(type(), VERSION)
var fl = require('../core/flNames')
var isArray = require('../core/isArray')
var isApply = require('../core/isApply')
var isApplicative = require('../core/isApplicative')
var isFunction = require('../core/isFunction')
var isSameType = require('../core/isSameType')
var _of =
Identity
function Identity(x) {
var obj;
if(!arguments.length) {
throw new TypeError('Identity: Must wrap something')
}
var valueOf =
function () { return x; }
var of =
_of
var equals =
function (m) { return isSameType(Identity, m)
&& _equals(x, m.valueOf()); }
var inspect =
function () { return ("Identity" + (_inspect(x))); }
function concat(method) {
return function(m) {
if(!isSameType(Identity, m)) {
throw new TypeError(("Identity." + method + ": Identity of Semigroup required"))
}
return _innerConcat(("Identity." + method), m)(x)
}
}
function map(method) {
return function(fn) {
if(!isFunction(fn)) {
throw new TypeError(("Identity." + method + ": Function required"))
}
return Identity(fn(x))
}
}
function ap(m) {
if(!isFunction(x)) {
throw new TypeError('Identity.ap: Wrapped value must be a function')
}
else if(!isSameType(Identity, m)) {
throw new TypeError('Identity.ap: Identity required')
}
return m.map(x)
}
function chain(method) {
return function(fn) {
if(!isFunction(fn)) {
throw new TypeError(("Identity." + method + ": Function required"))
}
var m = fn(x)
if(!isSameType(Identity, m)) {
throw new TypeError(("Identity." + method + ": Function must return an Identity"))
}
return m
}
}
function sequence(f) {
if(!(isApplicative(f) || isFunction(f))) {
throw new TypeError(
'Identity.sequence: Applicative TypeRep or Apply returning function required'
)
}
if(!(isApply(x) || isArray(x))) {
throw new TypeError('Identity.sequence: Must wrap an Apply')
}
return x.map(_of)
}
function traverse(f, fn) {
if(!(isApplicative(f) || isFunction(f))) {
throw new TypeError(
'Identity.traverse: Applicative TypeRep or Apply returning function required for first argument'
)
}
if(!isFunction(fn)) {
throw new TypeError(
'Identity.traverse: Apply returning functions required for second argument'
)
}
var m = fn(x)
if(!(isApply(m) || isArray(m))) {
throw new TypeError(
'Identity.traverse: Both functions must return an Apply of the same type'
)
}
return m.map(_of)
}
return ( obj = {
inspect: inspect, toString: inspect, valueOf: valueOf,
type: type, equals: equals, ap: ap, of: of, sequence: sequence, traverse: traverse,
concat: concat('concat'),
map: map('map'),
chain: chain('chain')
}, obj[fl.of] = of, obj[fl.equals] = equals, obj[fl.concat] = concat(fl.concat), obj[fl.map] = map(fl.map), obj[fl.chain] = chain(fl.chain), obj['@@type'] = _type, obj.constructor = Identity, obj )
}
Identity.of = _of
Identity.type = type
Identity[fl.of] = _of
Identity['@@type'] = _type
Identity['@@implements'] = _implements(
[ 'ap', 'chain', 'concat', 'equals', 'map', 'of', 'traverse' ]
)
module.exports = Identity