Skip to content

Instantly share code, notes, and snippets.

@edvardm
Last active August 29, 2015 14:13
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 edvardm/504b9b679c0f18a054e0 to your computer and use it in GitHub Desktop.
Save edvardm/504b9b679c0f18a054e0 to your computer and use it in GitHub Desktop.
Simple maybe for Ruby
# mimic behaviour of Haskell, idea taken mostly from
# https://github.com/tomstuart/monads/
Maybe = Struct.new(:value) do
# map value to monadic context, unless it's already
def self.unit(value)
value.kind_of?(Maybe) ? value : new(value)
end
# maybes = [nil, 1, 2].map { |i| Maybe.new(i) }
# Maybe.detect_m(maybes) { |i| i.even? }.value # 2
def self.detect_m(lst, &orig_block)
block = orig_block ? orig_block : -> (x) { x }
unit(
lst.detect do |m_item|
ensure_monadic(m_item).bind { |v| block.call(v) }.value
end
)
end
def bind(&block)
value.nil? ? self : self.class.unit(block.call(value))
end
alias >> bind
private
NonMonadicValue = Class.new(StandardError)
def self.ensure_monadic(item)
item.tap do
raise NonMonadicValue, item unless item.kind_of?(Maybe)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment