Module: Either
Overview
The ‘Either` union type represents values with two possibilities:
‘Either a b` is either `Left a` or `Right b`
Class Method Summary collapse
- .lefts(list_of_either) ⇒ value
- .partition(list_of_either) ⇒ [l], [r]
- .rights(list_of_either) ⇒ value
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
comparable - Left < Right.
-
#bimap(lfn, rfn) ⇒ Either
‘bimap` accept 2 lambdas, if it’s [Right], apply the 2nd lambda, otherwise apply to the first lambda.
- #each(&block) ⇒ Object
-
#flat_map ⇒ Either
it override Monad#flat_map, as Haskell’s ‘>flat_map` method if it’s Right, pass the value to #flat_map’s block, and flat the result of the block.
-
#get_or_else(e) ⇒ Object
(also: #|)
get value ‘a` out from `Right a`, otherwise return `e` “`ruby Right.new(1).get_or_else(2) # => 1 Right.new(1) | 2 # => 1 “`.
-
#initialize(v) ⇒ Either
Either only contain one value @v.
- #inspect ⇒ String
- #left? ⇒ Boolean
-
#left_map ⇒ Either
the opposit of #map, apply function to ‘Left e`, do nothing if it’s ‘Right a`.
-
#map ⇒ Either
overide of Functor’s ‘fmap`, apply function on `Right a`’s value ‘a`, do nothing if it’s ‘Left e`.
- #or_else(e) ⇒ Object
- #right? ⇒ Boolean
- #to_a ⇒ Object
-
#when(what) ⇒ Either
(also: #match, #=~)
similar to Scala’s ‘match` for case class.
-
#~@ ⇒ Either
(also: #swap)
swap type of [Either].
Methods included from Control::Monad
Methods included from Helper
Class Method Details
.lefts(list_of_either) ⇒ value
210 211 212 213 |
# File 'lib/data.either.rb', line 210 def lefts list_of_either list_of_either.select(&:left?) .map { |left| left.when({Left: ->l{l}}) } end |
.partition(list_of_either) ⇒ [l], [r]
221 222 223 224 225 226 227 228 229 |
# File 'lib/data.either.rb', line 221 def partition list_of_either list_of_either.inject([[],[]]) do |acc, x| x.when({ Left: ->(l){acc[0].push(l)}, Right: ->(r){acc[1].push(r)} }) acc end end |
.rights(list_of_either) ⇒ value
199 200 201 202 |
# File 'lib/data.either.rb', line 199 def rights list_of_either list_of_either.select(&:right?) .map { |right| right.get_or_else(nil) } end |
Instance Method Details
#<=>(other) ⇒ Object
comparable
-
Left < Right
171 172 173 174 175 176 177 178 179 180 |
# File 'lib/data.either.rb', line 171 def <=> other case self when Right other =~ {Right: ->o{ @v <=> o}, Left: ->_{1}} else other =~ {Right: ->_{ -1 }, Left: ->o{ @v <=> o}} end end |
#bimap(lfn, rfn) ⇒ Either
‘bimap` accept 2 lambdas, if it’s [Right], apply the 2nd lambda, otherwise apply to the first lambda
“‘ ruby
Right.new(1).bimap ->(x){x-1}, ->(x){x+1} # => 2
Left.new(1).bimap ->(x){x-1}, ->(x){x+1}) # => 0
“‘
90 91 92 93 94 95 96 97 |
# File 'lib/data.either.rb', line 90 def bimap lfn, rfn case self when Right Right.new(rfn.(@v)) else Left.new(lfn.(@v)) end end |
#each(&block) ⇒ Object
156 157 158 |
# File 'lib/data.either.rb', line 156 def each &block bimap(->_{}, &blcok) end |
#flat_map ⇒ Either
it override Monad#flat_map, as Haskell’s ‘>flat_map` method if it’s Right, pass the value to #flat_map’s block, and flat the result of the block.
when it’s Left, do nothing “‘ ruby expect(Right.new(1).flat_map { |x| Left.new } ).to eq(Left.new) expect(Left.new(1).flat_map { |x| Left.new } ).to eq(Left.new(1)) “`
109 110 111 112 113 114 115 116 |
# File 'lib/data.either.rb', line 109 def flat_map case self when Right yield @v else self end end |
#get_or_else(e) ⇒ Object Also known as: |
get value ‘a` out from `Right a`, otherwise return `e` “`ruby Right.new(1).get_or_else(2) # => 1 Right.new(1) | 2 # => 1 “`
31 32 33 34 35 36 37 38 |
# File 'lib/data.either.rb', line 31 def get_or_else e case self when Right @v else e end end |
#initialize(v) ⇒ Either
Either only contain one value @v
12 13 14 |
# File 'lib/data.either.rb', line 12 def initialize v @v = v end |
#inspect ⇒ String
183 184 185 186 187 188 189 190 |
# File 'lib/data.either.rb', line 183 def inspect case self when Left "#<Left value=#{@v}>" else "#<Right value=#{@v}>" end end |
#left? ⇒ Boolean
18 19 20 |
# File 'lib/data.either.rb', line 18 def left? false end |
#left_map ⇒ Either
74 75 76 77 78 79 80 81 |
# File 'lib/data.either.rb', line 74 def left_map case self when Left Left.new(yield @v) else self end end |
#map ⇒ Either
59 60 61 62 63 64 65 66 |
# File 'lib/data.either.rb', line 59 def map case self when Right Right.new(yield @v) else self end end |
#or_else(e) ⇒ Object
42 43 44 45 46 47 48 49 |
# File 'lib/data.either.rb', line 42 def or_else e case self when Right else e end end |
#right? ⇒ Boolean
22 23 24 |
# File 'lib/data.either.rb', line 22 def right? false end |
#to_a ⇒ Object
160 161 162 163 164 165 166 167 |
# File 'lib/data.either.rb', line 160 def to_a case self when Right [@v] else [] end end |
#when(what) ⇒ Either Also known as: match, =~
similar to Scala’s ‘match` for case class
will pattern match the value out and pass to matched lambda “‘ruby Right.new(1).when(->x{x+1 }) # => 2 Right.new(1).when(->x{x+1) # => nil Right.new(1) =~ (->x{x+1, _: ->xx-1 }) # => 0 “`
127 128 129 130 131 132 133 134 |
# File 'lib/data.either.rb', line 127 def when what current_class = self.class.to_s.to_sym if what.include? current_class what[current_class].(@v) elsif what.include? :_ what[:_].(@v) end end |