class Rumonade::Either
Represents a value of one of two possible types (a disjoint union). The data constructors {Rumonade::Left} and {Rumonade::Right} represent the two possible values. The Either
type is often used as an alternative to {Rumonade::Option} where {Rumonade::Left} represents failure (by convention) and {Rumonade::Right} is akin to {Rumonade::Some}.
This implementation of Either
also contains ideas from the Validation
class in the scalaz
library.
@abstract
Constants
- DEFAULT_CONCAT
Default concatenation function used by {#+}
Public Class Methods
# File lib/rumonade/either.rb, line 14 def initialize raise(TypeError, "class Either is abstract; cannot be instantiated") if self.class == Either end
Public Instance Methods
@param [Either] other the other Either
to concatenate @param [Hash] opts the options to concatenate with @option opts [Proc] :concat_left (DEFAULT_CONCAT
) The function to concatenate Left
values @option opts [Proc] :concat_right (DEFAULT_CONCAT
) the function to concatenate Right
values @yield [right_value] optional block to transform concatenated Right
values @yieldparam [Object] right_values the concatenated Right
values yielded to optional block @return [Either] if both are Right
, returns Right
with right_value
‘s concatenated,
otherwise a +Left+ with +left_value+'s concatenated
# File lib/rumonade/either.rb, line 62 def +(other, opts = {}) opts = { :concat_left => DEFAULT_CONCAT, :concat_right => DEFAULT_CONCAT }.merge(opts) result = case self when Left case other when Left then Left(opts[:concat_left].call(self.left_value, other.left_value)) when Right then Left(self.left_value) end when Right case other when Left then Left(other.left_value) when Right then Right(opts[:concat_right].call(self.right_value, other.right_value)) end end if block_given? then result.right.map { |right_values| yield right_values } else result end end
@param [Proc] function_of_left_value the function to apply if this is a Left
@param [Proc] function_of_right_value the function to apply if this is a Right
@return Returns the results of applying the function
# File lib/rumonade/either.rb, line 37 def fold(function_of_left_value, function_of_right_value) if left? then function_of_left_value.call(left_value) else function_of_right_value.call(right_value) end end
@return [Boolean] Returns true
if this is a {Rumonade::Left}, false
otherwise.
# File lib/rumonade/either.rb, line 20 def left? is_a?(Left) end
@param [#unit] monad_class the {Monad} to lift the Left
or Right
value into @return [Either] returns an +Either+of the same type, with the left_value
or right_value
lifted into +monad_class+
# File lib/rumonade/either.rb, line 90 def lift(monad_class) fold(lambda {|l| Left(monad_class.unit(l)) }, lambda {|r| Right(monad_class.unit(r))}) end
@return [Either] returns an Either
of the same type, with the left_value
or right_value
lifted into an +Array+
# File lib/rumonade/either.rb, line 83 def lift_to_a lift(Array) end
@return [Boolean] Returns true
if this is a {Rumonade::Right}, false
otherwise.
# File lib/rumonade/either.rb, line 25 def right? is_a?(Right) end