Created
September 1, 2014 11:52
-
-
Save lloeki/036a3699c4f9e715b78f to your computer and use it in GitHub Desktop.
Identity monad in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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