Skip to content

Instantly share code, notes, and snippets.

@guilleiguaran
Last active September 7, 2015 04:18
Show Gist options
  • Save guilleiguaran/9d8c672978df507a5e63 to your computer and use it in GitHub Desktop.
Save guilleiguaran/9d8c672978df507a5e63 to your computer and use it in GitHub Desktop.
Maybe Monad
require 'singleton'
class Maybe
def self.unit(value)
if value.nil? || (value.respond_to?(:empty?) && value.empty?)
Nothing.instance
else
Just.new(value)
end
end
end
class Just < Maybe
attr_reader :value
def initialize(value)
@value = value
end
def bind
yield @value
end
def empty?
false
end
def inspect
"Just(#{@value.inspect})"
end
end
class Nothing < Maybe
include Singleton
def bind
self
end
def empty?
true
end
def inspect
"Nothing"
end
end
@guilleiguaran
Copy link
Author

Example: Math.safe_log

module Math
  def self.safe_log(num, base = Math::E)
    if num < 0 || base < 0
      Nothing
    else
      Just.new(log(num,base))
    end
  end
end

@guilleiguaran
Copy link
Author

Maybe.unit("hello").bind{|x| Maybe.unit(x*2)}.bind{|x| Maybe.unit(x.length)}

Maybe.unit(nil).bind{|x| Maybe.unit(x*2)}.bind{|x| Maybe.unit(x.length)}

@guilleiguaran
Copy link
Author

# person.partner.name
Maybe.unit(person).bind{|x| Maybe.unit(x.partner)}.bind{|x| Maybe.unit(x.name)}

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