crocks
Version:
A collection of well known Algebraic Datatypes for your utter enjoyment.
127 lines (93 loc) • 3.18 kB
JavaScript
/** @license ISC License (c) copyright 2016 original and current authors */
/** @author Ian Hofmann-Hicks (evil) */
var VERSION = 2
var _equals = require('../core/equals')
var _implements = require('../core/implements')
var _inspect = require('../core/inspect')
var __type = require('../core/types').type('Writer')()
var _typeString = require('../core/types').typeFn(__type, VERSION)
var fl = require('../core/flNames')
var Pair = require('../core/Pair')
var isFunction = require('../core/isFunction')
var isMonoid = require('../core/isMonoid')
var isSameType = require('../core/isSameType')
var constant = function (x) { return function () { return x; }; }
function _Writer(Monoid) {
if(!isMonoid(Monoid)) {
throw new TypeError('Writer: Monoid required for construction')
}
var _of =
function (x) { return Writer(Monoid.empty().valueOf(), x); }
var _type =
constant((__type + "( " + (Monoid.type()) + " )"))
var typeString =
_typeString + "( " + (Monoid['@@type']) + " )"
function Writer(entry, val) {
var obj;
if(arguments.length !== 2) {
throw new TypeError('Writer: Log entry and a value required')
}
var type =
_type
var of =
_of
var equals =
function (m) { return isSameType(Writer, m)
&& _equals(m.valueOf(), val); }
var valueOf =
constant(val)
var log =
constant(Monoid(entry))
var inspect =
constant(("Writer(" + (_inspect(log())) + (_inspect(valueOf())) + " )"))
var read = function () { return Pair(log(), val); }
function map(method) {
return function(fn) {
if(!isFunction(fn)) {
throw new TypeError(("Writer." + method + ": Function required"))
}
return Writer(log().valueOf(), fn(valueOf()))
}
}
function ap(m) {
if(!isFunction(val)) {
throw new TypeError('Writer.ap: Wrapped value must be a function')
}
if(!isSameType(Writer, m)) {
throw new TypeError('Writer.ap: Writer required')
}
return Writer(
log().concat(m.log()).valueOf(),
val(m.valueOf())
)
}
function chain(method) {
return function(fn) {
if(!isFunction(fn)) {
throw new TypeError(("Writer." + method + ": Function required"))
}
var w = fn(valueOf())
if(!isSameType(Writer, w)) {
throw new TypeError(("Writer." + method + ": Function must return a Writer"))
}
return Writer(log().concat(w.log()).valueOf(), w.valueOf())
}
}
return ( obj = {
inspect: inspect, toString: inspect, read: read,
valueOf: valueOf, log: log, type: type, equals: equals,
ap: ap, of: of,
chain: chain('chain'),
map: map('map')
}, obj[fl.of] = of, obj[fl.equals] = equals, obj[fl.map] = map(fl.map), obj[fl.chain] = chain(fl.chain), obj['@@type'] = typeString, obj.constructor = Writer, obj )
}
Writer.of = _of
Writer.type = _type
Writer[fl.of] = _of
Writer['@@type'] = typeString
Writer['@@implements'] = _implements(
[ 'ap', 'chain', 'equals', 'map', 'of' ]
)
return Writer
}
module.exports = _Writer