Fantasy Land Specification
(aka "Algebraic JavaScript Specification")
This project specifies interoperability of common algebraic structures:
- Functor
- Monad
General
An algebra is a set of values, a set of operators that it is closed under and some laws it must obey.
Terminology
- "value" is any JavaScript value, including any which have the structures defined below.
Algebras
Functor
Functor values MUST implement map
function that complies to
a following rules:
map(u, function(a) { return a; })
equalsu
map(u, function(x) { return f(g(x)); })
equalsmap(map(u, g), f)
map
function
A value which has a functor must provide a map
implementation. That takes
functor value and f
function:
map.define(u, function(u, f) {
// ...
})
-
f
must be a function,- If
f
is not a function, the behaviour ofmap
is unspecified. f
can return any value.
- If
-
map
must return a value of the same functor
Monad
A value which satisfies the specification of a monad do not need to implement:
Functor's map
as it's defined by default:
map.define(Object, function(wrapped, f) {
return flatMap(wrapped, function(unwrapped) {
return derive(wrapped, f(unwrapped));
});
});
of(a).then(f)
equalsf(a)
flatMap(m, function(u) { return derive(m, u) })
equalsm
m.then(of)
equalsm
m.then(f).then(g)
equalsm.then(function(x) { return f(x).then(g); })
flatMap
function
A value which is a monad must provide a flatMap
implementation. The flatMap
function takes m
monad and f
function as arguments:
flatMap(m, f)
-
f
must be a function which returns a value- If
f
is not a function, the behaviour offlatMap
is unspecified. f
must return a value of the same monad
- If
-
flatMap
must return a value of the same monad
derive
function
A value which has a monad must provide derive
implementation.
Implementation must take source
argument and value
:
derive(m, a)
-
derive
must provide a value of the same monad- No parts of
a
should be checked
- No parts of