This is an example of use of the new approach for fantasy-land proposed in fantasyland/fantasy-land#199
Read this commnet to understand what "Spec compatible Type Representative" and "spec compatible value" means.
This is an example of use of the new approach for fantasy-land proposed in fantasyland/fantasy-land#199
Read this commnet to understand what "Spec compatible Type Representative" and "spec compatible value" means.
// This module exposes Representative that produces spec compatible values. | |
const Maybe = { | |
of(x) { | |
return { | |
'fantasy-land': Maybe, | |
type: 'just', | |
value: x, | |
} | |
}, | |
nothing: { | |
'fantasy-land': Maybe, | |
type: 'nothing', | |
}, | |
map(f, v) { | |
return v.type === 'nothing' ? v : Maybe.of(f(v.value)) | |
}, | |
ap(f, v) { | |
return f.type === 'nothing' ? f : (v.type === 'nothing' ? v : Maybe.of(f.value(v.value))) | |
}, | |
} | |
export {Maybe} |
// This module also exposes Representative that produces spec compatible values | |
// but uses JavaScript classes under the hood. | |
function IdC(x) { | |
this._x = x | |
} | |
const Id = { | |
of(x) { | |
return new IdC(x) | |
}, | |
map(f, v) { | |
return new IdC(f(v._x)) | |
}, | |
ap(f, v) { | |
return new IdC(f._x(v._x)) | |
} | |
} | |
IdC.prototype['fantasy-land'] = Id | |
export {Id} |
// Unlike in maybe.js and id.js in this module we expose Representatives | |
// that produce spec _incompatible_ values but Representatives themselves are compatible. | |
const List = { | |
of(x) {return [x]}, | |
map(f, v) {return v.map(f)}, | |
ap(f, v) {return f.map(f => v.map(f)).reduce((r, i) => r.concat(i), [])}, | |
} | |
const ZipList = { | |
of(x) {return [x]}, | |
map(f, v) {return v.map(f)}, | |
ap(f, v) {return f.map((f, i) => f(v[i]))}, | |
} | |
export {List, ZipList} |
// In this module we write code that works with spec compatible values. | |
// We don't have to pass Representatives around, but all values must have `fantasy-land` property. | |
import {Id} from 'id' | |
import {Maybe} from 'maybe' | |
// Generic code | |
function lift2(f, a, b) { | |
const T = a['fnatasy-land'] | |
return T.ap(T.map(a => b => f(a, b), a), b) | |
} | |
// App code | |
lift2((a, b) => a + b, Id.of(1), Id.of(2)) // Id.of(3) | |
lift2((a, b) => a + b, Maybe.of(1), Maybe.nothing) // Maybe.nothing |
// In this module we write code that works with spec compatible Type Representatives. | |
// We can use array.js here as well as maybe.js and id.js. | |
import {List, ZipList} from 'array' | |
import {Maybe} from 'maybe' | |
// Generic code | |
function lift2(T, f, a, b) { | |
return T.ap(T.map(a => b => f(a, b), a), b) | |
} | |
// App code | |
lift2(Id, (a, b) => a + b, Id.of(1), Id.of(2)) // Id.of(3) | |
lift2(List, (a, b) => a + b, [1, 2], [3, 4]) // [3, 5, 5, 6] | |
lift2(ZipList, (a, b) => a + b, [1, 2], [3, 4]) // [3, 6] |