Skip to content

Instantly share code, notes, and snippets.

@lloeki
Created September 1, 2014 11:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lloeki/036a3699c4f9e715b78f to your computer and use it in GitHub Desktop.
Save lloeki/036a3699c4f9e715b78f to your computer and use it in GitHub Desktop.
Identity monad in Ruby
# http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/01identity
# Identity monad
class Identity
def initialize(value)
@value = value
end
# unit operation: Haskell 'return'
def self.munit(value)
new(value)
end
# bind operation: Haskell '>>='
def bind(proc)
proc.call(@value)
end
# obtain value
attr_reader :value
# define equality
def hash
value.hash
end
end
# 0th rule
# maintain monad-land and value-land isolation
# functions passed to bind must return a monad
f = -> (value) do
new_value = value + 1 # process value
Identity::munit(new_value) # always return a monad
# or wrap nil if no return value
end
Identity.new(0).bind f
# 1st law
# unit must be left identity for bind:
# let f a function
# let v a value
# M.unit(v).bind(x -> f(x)) should == f(v)
# 2nd law
# unit must be right identity for bind:
# let v a value
# let m = M.unit(v)
# m.bind(x -> M.unit(x)) should == m
# 3rd law
# bind must be associative
# let v values
# let f, g functions
# let m = M.unit(v)
# m.bind(x -> f(x)).bind(x -> g(x)) should == m.bind(x -> f(x).bind(x -> g(x)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment