UNPKG

crocks

Version:

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

127 lines (93 loc) 3.18 kB
/** @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