Skip to content

Instantly share code, notes, and snippets.

@kputnam
Created April 2, 2012 23:51
Show Gist options
  • Save kputnam/2288109 to your computer and use it in GitHub Desktop.
Save kputnam/2288109 to your computer and use it in GitHub Desktop.
State monad in CoffeeScript
# Actions
###################################################################
put = (n) -> (state, count) ->
{state: n, value: null, count: count + 1}
get = (state, count) ->
{state: state, value: state, count: count}
update = (f) -> (state, count) ->
{state: f(state), value: null, count: count + 1}
# Combinators
###################################################################
unit = (value) -> (state, count) ->
{state: state, value: value, count: count}
bind = (x, f) -> (state, count) ->
tuple = x(state, count)
f(tuple.value)(tuple.state, tuple.count)
# Evaluators
###################################################################
# Return the entire monadic value (state, value, count)
run = (computation, initialState) ->
computation(initialState, 0)
# Return the resulting value
eval = (computation, initialState) ->
computation(initialState, 0).value
# Return the resulting state
exec = (computation, initialState) ->
computation(initialState, 0).state
# Return how many times state was written
count = (computation, initialState) ->
computation(initialState, 0).count
# Example
###################################################################
also = (a) -> (b) -> a && b
test =
bind get, (x) ->
bind put(x % 2 == 0), ->
bind update(also(x % 3 == 0)), ->
bind update(also(x % 5 == 0)), ->
bind get, (t) ->
unit(if x > 100 && t \
then "Big multiple of 2, 3, 5: #{x}"
else "Dunno: #{x}")
# This shows three writes to the state
# run(test, 300)
# run(test, 301)
if exports?
exports.put = put
exports.get = get
exports.update = update
exports.unit = unit
exports.bind = bind
exports.run = run
exports.eval = eval
exports.exec = exec
exports.count = count
exports.test = test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment