new Free()
The Free union type can be used to transform any structure into a monad. This means, Free can be used to create DSLs or custom interpreters for actions.
- Version:
- 3.0.0
- Source:
Example
const {Free} = require('futils').data;
const {Cont, Return} = Free;
Free.Cont(1, Free.Return); // -> Cont(1)
Cont(1, Return); // -> Cont(1)
Free.Return(1); // -> Return(1)
Return(1); // -> Return(1)
Methods
(static) from(F) → {Cont}
A shortcut version of Free.liftM, takes a constructor function and returns a lifted function which puts the resulting structure into a Free.Cont
- Source:
Parameters:
Name | Type | Description |
---|---|---|
F |
function
|
The constructor function to lift |
Returns:
- Type:
-
Cont
A Free.Cont instance
Example
const {UnionType} = require('futils').adt;
const {Free} = require('futils').data;
const {compose} = require('futils').lambda;
const Num = UnionType('Num', {Int: ['value'], Float: ['value']});
const {Int, Float} = Num;
const asInt = compose(Free.from(Int), parseInt);
const asFloat = compose(Free.from(Float), parseFloat);
const prog = asInt(100.25).map(n => n.toFixed(2)).flatMap(asFloat);
(static) liftM(a) → {Cont}
Lifts a structure into a Free.Cont
- Source:
Parameters:
Name | Type | Description |
---|---|---|
a |
any
|
The structure |
Returns:
- Type:
-
Cont
A Free.Cont instance
Example
const {UnionType} = require('futils').adt;
const {Free} = require('futils').data;
const Num = UnionType('Num', {Int: ['value'], Float: ['value']});
const {Int, Float} = Num;
const asInt = n => Free.liftM(Int(parseInt(n, 10)));
const asFloat = n => Free.liftM(Float(parseFloat(n)));
const prog = asInt(100.25).map(n => n.toFixed(2)).flatMap(asFloat);
(static) of(a) → {Return}
Lifts a value into a Free.Return
- Source:
Parameters:
Name | Type | Description |
---|---|---|
a |
any
|
The value to lift |
Returns:
- Type:
-
Return
A Free.Return instance
Example
const {Free} = require('futils').data;
Free.of(1); // -> Return(1)
ap(a) → {Return|Cont}
Free applicative implementation, applies a function in a Free to a value in another Free
- Source:
Parameters:
Name | Type | Description |
---|---|---|
a |
Return
|
Cont
|
The Free that holds the value |
Returns:
- Type:
-
Return
|Cont
Free which returns the result of applying the function
Example
const {Free} = require('futils').data;
Free.of(n => n + 1).ap(Free.of(1)); // -> Return(2)
flatMap(f) → {Return|Cont}
Maps a Free returning function over a Free.Return or Free.Cont and flattens the result
- Source:
Parameters:
Name | Type | Description |
---|---|---|
f |
function
|
A Free returning function to map |
Returns:
- Type:
-
Return
|Cont
A new Free
Example
const {Free} = require('futils').data;
Free.of(1).flatMap(n => Free.of(n + 1)); // -> Return(2)
interpret(transform, A) → {ApplicativeMonad}
If given a interpreter function, which should be a natural transformation, interprets the computation build with Free. This method is aliased to traverse.
- Source:
Parameters:
Name | Type | Description |
---|---|---|
transform |
function
|
The interpreter function |
A |
ApplicativeMonad
|
The data structure to interpret into |
Returns:
- Type:
-
ApplicativeMonad
A data structure which holds the result
Example
const {UnionType} = require('futils').adt;
const {Free, Id} = require('futils').data;
const Num = UnionType('Num', {Int: ['value'], Float: ['value']});
const {Int, Float} = Num;
const cmp = (f, g) => x => f(g(x));
const asInt = cmp(Free.from(Int), parseInt);
const asFloat = cmp(Free.from(Float), parseFloat);
const prog = asInt(100.25).map(n => n.toFixed(2)).flatMap(asFloat);
const nt = num => num.caseOf({
Int: n => isNaN(n) ? Id.of(0) : Id.of(Math.round(n)),
Float: n => isNaN(n) ? Id.of(0) : Id.of(n)
});
prog.interpret(nt, Id); // -> Id(100.00)
// or: prog.traverse(nt, Id); // -> Id(100.00)
map(f) → {Return|Cont}
Maps a function over a Free.Return or a Free.Cont and returns a new Free
- Source:
Parameters:
Name | Type | Description |
---|---|---|
f |
function
|
The function to map |
Returns:
- Type:
-
Return
|Cont
A new Free
Example
const {Free} = require('futils').data;
Free.of(1).map(n => n + 1); // -> Return(2)