Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/** Consider the interface
interface Mappable<A> {
map: (A → B) → Mappable<B>
}
*/
function Identity(value) {
return {
map: function(f){ return Identity(f(value)) }
}
}
function Sequence(xs) {
return {
map: function(f){ return Sequence(xs.map(f)) }
}
}
function Map(o) {
return {
map: function(f){ return Map(mapObject(f, o)) }
}
function mapObject(f, o){
return Object.keys(o).reduce(function(r, k){ r[k] = f(o[k]); return r }, {})
}
}
function Stream(h, t) {
return {
map: function(f){
return Stream(f(h), function(){ return t().map(f) })
}
}
}
Stream.Empty = {
map: function(){ return Stream.Empty }
}
// So we can use all of these "Mappable" interfaces without caring about the object:
function succ(a){ return a + 1 }
var id = Identity(1)
id.map(succ) // => Identity(2)
var xs = Sequence([1, 2, 3, 4])
xs.map(succ) // => Sequence([2, 3, 4, 5])
var o = Map({ a: 1, b: 2, c: 3 })
o.map(succ) // => Map({ a: 2, b: 3, c: 4 })
var s = Stream(1, function(){ return Stream(2, function(){ return Stream.Empty }) })
s.map(succ) // => Stream(2, lazy(3, lazy(Empty)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment