Class: Rumonade::Either Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/rumonade/either.rb,
lib/rumonade/either.rb

Overview

This class is abstract.

Represents a value of one of two possible types (a disjoint union). The data constructors Left and Right represent the two possible values. The Either type is often used as an alternative to Option where Left represents failure (by convention) and Right is akin to Some.

Direct Known Subclasses

Left, Right

Defined Under Namespace

Classes: LeftProjection, RightProjection

Constant Summary collapse

DEFAULT_CONCAT =

Default concatenation function used by #+

lambda { |a,b| a + b }

Instance Method Summary collapse

Instance Method Details

#+(other, opts = {}) {|right_value| ... } ⇒ Either Also known as: concat

Returns if both are Right, returns Right with right_value‘s concatenated, otherwise a Left with left_value’s concatenated.

Parameters:

  • other (Either)

    the other Either to concatenate

  • opts (Hash) (defaults to: {})

    the options to concatenate with

Options Hash (opts):

  • :concat_left (Proc) — default: DEFAULT_CONCAT

    The function to concatenate Left values

  • :concat_right (Proc) — default: DEFAULT_CONCAT

    the function to concatenate Right values

Yields:

  • (right_value)

    optional block to transform concatenated Right values

Yield Parameters:

  • right_values (Object)

    the concatenated Right values yielded to optional block

Returns:

  • (Either)

    if both are Right, returns Right with right_value‘s concatenated, otherwise a Left with left_value’s concatenated



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rumonade/either.rb', line 58

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

#fold(function_of_left_value, function_of_right_value) ⇒ Object

Returns the results of applying the function

Parameters:

  • function_of_left_value (Proc)

    the function to apply if this is a Left

  • function_of_right_value (Proc)

    the function to apply if this is a Right

Returns:

  • Returns the results of applying the function



33
34
35
# File 'lib/rumonade/either.rb', line 33

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

#leftLeftProjection

Returns Projects this Either as a Left.

Returns:



38
39
40
# File 'lib/rumonade/either.rb', line 38

def left
  LeftProjection.new(self)
end

#left?Boolean

Returns true if this is a Left, false otherwise.

Returns:

  • (Boolean)

    Returns true if this is a Left, false otherwise.



16
17
18
# File 'lib/rumonade/either.rb', line 16

def left?
  is_a?(Left)
end

#lift(monad_class) ⇒ Either

Returns an Eitherof the same type, with the left_value or right_value lifted into monad_class

Parameters:

  • monad_class (#unit)

    the Monad to lift the Left or Right value into

Returns:

  • (Either)

    returns an Eitherof the same type, with the left_value or right_value lifted into monad_class



86
87
88
# File 'lib/rumonade/either.rb', line 86

def lift(monad_class)
  fold(lambda {|l| Left(monad_class.unit(l)) }, lambda {|r| Right(monad_class.unit(r))})
end

#lift_to_aEither

Returns an Either of the same type, with the left_value or right_value lifted into an Array

Returns:

  • (Either)

    returns an Either of the same type, with the left_value or right_value lifted into an Array



79
80
81
# File 'lib/rumonade/either.rb', line 79

def lift_to_a
  lift(Array)
end

#rightRightProjection

Returns Projects this Either as a Right.

Returns:



43
44
45
# File 'lib/rumonade/either.rb', line 43

def right
  RightProjection.new(self)
end

#right?Boolean

Returns true if this is a Right, false otherwise.

Returns:

  • (Boolean)

    Returns true if this is a Right, false otherwise.



21
22
23
# File 'lib/rumonade/either.rb', line 21

def right?
  is_a?(Right)
end

#swapBoolean

Returns If this is a Left, then return the left value in Right or vice versa.

Returns:

  • (Boolean)

    If this is a Left, then return the left value in Right or vice versa.



26
27
28
# File 'lib/rumonade/either.rb', line 26

def swap
  if left? then Right(left_value) else Left(right_value) end
end