-
-
Save buzzdecafe/df9287ba30ffcfd69d6603c442f96921 to your computer and use it in GitHub Desktop.
A Fantasy Land-compliant type for lazy computation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Some lazily-evaluated thunk. | |
const thunk = Lazy[fl.of](2)[fl.map](x => 'My number is ' + x) | |
[fl.map](console.log.bind(console)) | |
// No console log... | |
// ... until we `run` the laziness: | |
thunk.run() // Logs "My number is 2" | |
// * You can also build infinite lists! * // | |
// Create an infinite list froma given start | |
const countUp = head => ({ | |
head, | |
tail: Lazy[fl.of](head + 1)[fl.map](countUp) | |
}) | |
console.log( | |
countUp(2).head, // 2 | |
countUp(2).tail.run().head // 3 | |
// ... etc | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fl = require('fantasy-land') | |
//- Lazy holds a vaue in a thunk, effectively delaying | |
//- evaluation until required. This is useful when we're | |
//- in a situation with either very large data set or | |
//- cyclical data. | |
//@ make stack-safe. | |
//> type Lazy a = Unit -> a | |
function Lazy(run) { | |
if (this.constructor !== Lazy) | |
return new Lazy(run) | |
this.run = run | |
} | |
/* Semigroup Lazy */ { | |
Lazy.prototype[fl.concat] = function (that) { | |
return Lazy(() => this.run()[fl.concat](that.run())) | |
} | |
} | |
// Monoid instance requires TypeRep | |
/* Functor Lazy */ { | |
Lazy.prototype[fl.map] = function (f) { | |
return Lazy(() => f(this.run())) | |
} | |
} | |
/* Apply Lazy */ { | |
Lazy.prototype[fl.ap] = function (that) { | |
return Lazy(() => that.run()(this.run())) | |
} | |
} | |
/* Applicative Lazy */ { | |
Lazy[fl.of] = value => | |
Lazy(() => value) | |
} | |
/* Alt Lazy */ { | |
Lazy.prototype[fl.alt] = function (that) { | |
return Lazy(() => this.run().alt(that.run())) | |
} | |
} | |
// Plus instance requires TypeRep | |
/* Chain Lazy */ { | |
Lazy[fl.chain] = function (f) { | |
return Lazy(() => f(this.run()).run()) | |
} | |
} | |
// Are Extend/Comonad useful here? | |
/* Extend Lazy */ { | |
Lazy[fl.extend] = function (f) { | |
return Lazy(() => f(this)) | |
} | |
} | |
/* Comonad Lazy */ { | |
Lazy[fl.extract] = function () { | |
return this.run() | |
} | |
} | |
module.exports = Lazy |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment