Last active
December 20, 2015 22:48
-
-
Save guilleiguaran/6207355 to your computer and use it in GitHub Desktop.
Maybe monad
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
# Consider the option type Maybe(a), representing a value that is either a single value of type a, or no value at all. | |
# To distinguish these, we have two algebraic data type constructors: Just(x), containing the value x, or Nothing, | |
# containing no value. | |
# | |
# data Maybe(t) = Just(t) | Nothing | |
# | |
# We would like to be able to use this type as a simple sort of checked exception: at any point in a computation, | |
# the computation may fail, which causes the rest of the computation to be skipped and the final result to be Nothing. | |
# If all steps of the calculation succeed, the final result is Just(x) for some value x. | |
require 'singleton' | |
class Maybe | |
def self.wrap(value) | |
if value.nil? || (value.respond_to?(:empty?) && value.empty?) | |
Nothing.instance | |
else | |
Just.new(value) | |
end | |
end | |
def method_missing(method, *args, &block) | |
pass(&lambda{|value| Maybe.wrap(value.send(method, *args, &block))}) | |
end | |
end | |
class Just < Maybe | |
attr_reader :value | |
def initialize(value) | |
@value = value | |
end | |
def pass(&block) | |
block.call(@value) | |
end | |
def empty? | |
false | |
end | |
def maybe(default_value) | |
@value | |
end | |
def inspect | |
"Just(#{@value.inspect})" | |
end | |
end | |
class Nothing < Maybe | |
include Singleton | |
def pass | |
self | |
end | |
def empty? | |
true | |
end | |
def maybe(default_value) | |
default_value | |
end | |
def inspect | |
"Nothing" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage: