Skip to content

Instantly share code, notes, and snippets.

@DrBoolean
Last active March 17, 2024 10:33
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save DrBoolean/34c1d3651d1338b1b187 to your computer and use it in GitHub Desktop.
Save DrBoolean/34c1d3651d1338b1b187 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
@DrBoolean
Copy link
Author

@RPallas92
Copy link

What is the cata property of the free monad?

@kwijibo
Copy link

kwijibo commented Mar 18, 2016

cata is from the daggy library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment