Skip to content

Instantly share code, notes, and snippets.

@arcseldon
Forked from DrBoolean/free-er.js
Created February 28, 2016 06:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arcseldon/c91e98a64069b6d010a4 to your computer and use it in GitHub Desktop.
Save arcseldon/c91e98a64069b6d010a4 to your computer and use it in GitHub Desktop.
Free(er) monads in JS (pt 1)
const daggy = require('daggy')
const compose = (f, g) => x => f(g(x))
const id = x => x
const kleisli_comp = (f, g) => x => f(x).chain(g)
//=============FREE=============
const Free = daggy.taggedSum({Impure: ['x', 'f'], Pure: ['x']})
const {Impure, Pure} = Free
Free.of = Pure
Free.prototype.chain = function(f) {
return this.cata({
Impure: (x, g) => Impure(x, kleisli_comp(g, f)),
Pure: x => f(x)
})
}
Free.prototype.map = function(f) {
return this.chain(a => Free.of(f(a)))
}
const liftF = command => Impure(command, Pure)
//=============IO via FREE=============
const IO = daggy.taggedSum({IO: ['f']})
const io = compose(liftF, IO.IO)
const unsafePerformIO = free =>
free.cata({
Pure: id,
Impure: (m, q) =>
unsafePerformIO(q(m.f()))
})
//=============Maybe via FREE=============
const Maybe = daggy.taggedSum({ Just: ['x'], Nothing: [] })
const {Just, Nothing} = Maybe
const just = compose(liftF, Just)
const nothing = liftF(Nothing)
const runMaybe = free =>
free.cata({
Pure: x => x,
Impure: (m, q) =>
m.cata({
Just: x => runMaybe(q(x)),
Nothing: () => Nothing
})
})
//=============Examples=============
const safeProp = (k, o) => o[k] ? just(o[k]) : nothing
const localStorage = io(() => ({preferences: 'blue'}))
const printLn = x => io(() => console.log(x))
//maybe_name :: Free (Maybe String)
const maybe_name = safeProp('user', {user: {name: 'jerry'}})
.chain(u => safeProp('name', u))
.map(n => n.toUpperCase())
runMaybe(maybe_name)
// JERRY
//i :: Free (IO ())
const i = localStorage
.map(l => l.preferences)
.chain(printLn)
unsafePerformIO(i)
// blue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment