lib/either/match.rb
module Either
class Match
def initialize
@lefts = []
@rights = []
end
def left pattern=always, &block
@lefts << [(lambify pattern), block]
end
def right pattern=always, &block
@rights << [(lambify pattern), block]
end
def evaluate(either)
Evaluation.new(self, either).result
end
attr_reader :lefts, :rights
private
def lambify(pattern)
pattern.is_a?(Proc) ? pattern : ->(x){ x == pattern }
end
def always
->(x) { true }
end
class Evaluation
def initialize(match, either)
@match = match
@either = either
end
attr_reader :match, :either
def result
either.left? ? left_result : right_result
end
private
def left_result
left_match.call(either.left.value)
end
def right_result
right_match.call(either.right.value)
end
def left_match
lefts.find { |pattern, _| either.left.select(&pattern).some? }.last
end
def right_match
rights.find { |pattern, _| either.right.select(&pattern).some? }.last
end
def lefts
match.lefts
end
def rights
match.rights
end
end
end
end