data.either 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/control/monad.rb +5 -6
  3. data/lib/data.either.rb +106 -41
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 08f4e5166ec1ad8d037c1242ad30dc3ea9e60e4c
4
- data.tar.gz: f3fc3a10f5aede1bc5b949b664fe65979f619785
3
+ metadata.gz: 9c33caadee9fe0b72c04d63bb00cb0bcd6b80cbe
4
+ data.tar.gz: dcfc0d9d6ac4f8203656e9dca564ce4b0b07f230
5
5
  SHA512:
6
- metadata.gz: 5f31fccf30c2341d5bfce564060eddf90172613147663f52d48e6efd301b407ed0716d282c52c6097a7dd10e247d7de5e096b834b0760ea941f796004260c605
7
- data.tar.gz: 980bb06448d07169db9c62a1ab80b27a33bca1d7ce56019c5447f28cfadfda392fd9dc2d53aebb925ec0dbcc4a8fe831773bea65b583a77b69c6dea58fe156bd
6
+ metadata.gz: 2aaa80d55efd1a9b9214cdfe61008873ea29558c9f3c9893de69cb9a5528fbbebed7683cb094913ab8981274ee0a6e70161448e4b6521791f0ed685ba971051a
7
+ data.tar.gz: c421608cce3d4488011e087533814890c3eb84949fcd37b06040ce03d1300fbdccbccf2afa5d77ce72b0675e2ec380f7972f4a582085857090b9272b5ba6e524
data/lib/control/monad.rb CHANGED
@@ -3,20 +3,19 @@ module Control
3
3
  module Functor
4
4
  extend Helper
5
5
  def map
6
+ raise 'map No defined'
6
7
  end
7
8
  end
8
9
 
9
10
  module Monad
10
11
  extend Helper
11
12
  include Functor
12
- def >=
13
- raise '>= No defined'
13
+ def flat_map
14
+ raise 'flat_map No defined'
14
15
  end
15
-
16
- alias_names([:flat_map], :>=)
17
16
 
18
- def > k
19
- self.>= { |_| k }
17
+ def >> k
18
+ self.flat_map { |_| k }
20
19
  end
21
20
  end
22
21
 
data/lib/data.either.rb CHANGED
@@ -4,6 +4,7 @@ require 'control/monad'
4
4
  #
5
5
  # `Either a b` is either `Left a` or `Right b`
6
6
  module Either
7
+ include Comparable
7
8
  include Control::Monad
8
9
 
9
10
  # Either only contain one value @v
@@ -23,6 +24,10 @@ module Either
23
24
  end
24
25
 
25
26
  # get value `a` out from `Right a`, otherwise return `e`
27
+ # ```ruby
28
+ # Right.new(1).get_or_else(2) # => 1
29
+ # Right.new(1) | 2 # => 1
30
+ # ```
26
31
  def get_or_else e
27
32
  case self
28
33
  when Right
@@ -32,6 +37,18 @@ module Either
32
37
  end
33
38
  end
34
39
 
40
+ alias_method :|, :get_or_else
41
+
42
+ def or_else e
43
+ case self
44
+ when Right
45
+
46
+ else
47
+ e
48
+ end
49
+ end
50
+
51
+
35
52
  # overide of Functor's `fmap`, apply function on `Right a`'s value `a`, do nothing if it's `Left e`
36
53
  #
37
54
  # ``` ruby
@@ -79,17 +96,17 @@ module Either
79
96
  end
80
97
  end
81
98
 
82
- # it override {Monad#>=}, as Haskell's `>>=` method
83
- # if it's {Right}, pass the value to #>='s block, and flat the result
99
+ # it override {Monad#flat_map}, as Haskell's `>flat_map` method
100
+ # if it's {Right}, pass the value to #flat_map's block, and flat the result
84
101
  # of the block.
85
102
  #
86
103
  # when it's {Left}, do nothing
87
104
  # ``` ruby
88
- # expect(Right.new(1).>= { |x| Left.new } ).to eq(Left.new)
89
- # expect(Left.new(1).>= { |x| Left.new } ).to eq(Left.new(1))
105
+ # expect(Right.new(1).flat_map { |x| Left.new } ).to eq(Left.new)
106
+ # expect(Left.new(1).flat_map { |x| Left.new } ).to eq(Left.new(1))
90
107
  # ```
91
108
  # @return [Either]
92
- def >=
109
+ def flat_map
93
110
  case self
94
111
  when Right
95
112
  yield @v
@@ -101,11 +118,10 @@ module Either
101
118
  # similar to Scala's `match` for case class
102
119
  #
103
120
  # will pattern match the value out and pass to matched lambda
104
- #
105
- # ``` ruby
121
+ # ```ruby
106
122
  # Right.new(1).when({Right: ->x{x+1} }) # => 2
107
123
  # Right.new(1).when({Left: ->x{x+1}) # => nil
108
- # Right.new(1).when({Left: ->x{x+1}, _: ->x{x-1} }) # => 0
124
+ # Right.new(1) =~ ({Left: ->x{x+1}, _: ->x{x-1} }) # => 0
109
125
  # ```
110
126
  # @return [Either]
111
127
  def when what
@@ -117,6 +133,52 @@ module Either
117
133
  end
118
134
  end
119
135
 
136
+ alias_method :match, :when
137
+ alias_method :=~, :when
138
+
139
+ # swap type of [Either]
140
+ #
141
+ # ```ruby
142
+ # ~Right.new(1) # => Left.new(1)
143
+ # ~Left.new(2) # => Right.new(2)
144
+ # ```
145
+ # @return [Either]
146
+ def ~@
147
+ case self
148
+ when Right
149
+ Left.new @v
150
+ else
151
+ Right.new @v
152
+ end
153
+ end
154
+
155
+ alias_method :swap, :~@
156
+ def each &block
157
+ bimap(->_{}, &blcok)
158
+ end
159
+
160
+ def to_a
161
+ case self
162
+ when Right
163
+ [@v]
164
+ else
165
+ []
166
+ end
167
+ end
168
+
169
+ # comparable
170
+ # - Left < Right
171
+ def <=> other
172
+ case self
173
+ when Right
174
+ other =~ {Right: ->o{ @v <=> o},
175
+ Left: ->_{1}}
176
+ else
177
+ other =~ {Right: ->_{ -1 },
178
+ Left: ->o{ @v <=> o}}
179
+ end
180
+ end
181
+
120
182
  # @return [String]
121
183
  def inspect
122
184
  case self
@@ -127,43 +189,46 @@ module Either
127
189
  end
128
190
  end
129
191
 
130
- # filter only {Right} value from List of {Either}
131
- #
132
- # ``` ruby
133
- # Either.rights [Left.new(1),Right.new(5), Right.new(2)] # => [5, 2]
134
- # ```
135
- # @return [value]
136
- def self.rights list_of_either
137
- list_of_either.select(&:right?)
138
- .map { |right| right.get_or_else(nil) }
139
- end
192
+ class << self
193
+ # filter only {Right} value from List of {Either}
194
+ #
195
+ # ``` ruby
196
+ # Either.rights [Left.new(1),Right.new(5), Right.new(2)] # => [5, 2]
197
+ # ```
198
+ # @return [value]
199
+ def rights list_of_either
200
+ list_of_either.select(&:right?)
201
+ .map { |right| right.get_or_else(nil) }
202
+ end
140
203
 
141
- # filter only {Left} value from List of {Either}
142
- #
143
- # ``` ruby
144
- # Either.lefts [Left.new(1),Right.new(5), Right.new(2)] # => [1]
145
- # ```
146
- # @return [value]
147
- def self.lefts list_of_either
148
- list_of_either.select(&:left?)
149
- .map { |left| left.when({Left: ->l{l}}) }
150
- end
204
+ # filter only {Left} value from List of {Either}
205
+ #
206
+ # ``` ruby
207
+ # Either.lefts [Left.new(1),Right.new(5), Right.new(2)] # => [1]
208
+ # ```
209
+ # @return [value]
210
+ def lefts list_of_either
211
+ list_of_either.select(&:left?)
212
+ .map { |left| left.when({Left: ->l{l}}) }
213
+ end
151
214
 
152
- # partion a List of {Either} into a List of 2 List, one contains only {Left}, other contains only {Right}
153
- #
154
- # ``` ruby
155
- # Either.partition [Left.new(1),Right.new(5), Right.new(2)] # => [[1],[5, 2]]
156
- # ```
157
- # @return [[l],[r]]
158
- def self.partition list_of_either
159
- list_of_either.inject([[],[]]) do |acc, x|
160
- x.when({
161
- Left: ->(l){acc[0].push(l)},
162
- Right: ->(r){acc[1].push(r)}
163
- })
164
- acc
215
+ # partion a List of {Either} into a List of 2 List, one contains only {Left}, other contains only {Right}
216
+ #
217
+ # ``` ruby
218
+ # Either.partition [Left.new(1),Right.new(5), Right.new(2)] # => [[1],[5, 2]]
219
+ # ```
220
+ # @return [[l],[r]]
221
+ def partition list_of_either
222
+ list_of_either.inject([[],[]]) do |acc, x|
223
+ x.when({
224
+ Left: ->(l){acc[0].push(l)},
225
+ Right: ->(r){acc[1].push(r)}
226
+ })
227
+ acc
228
+ end
165
229
  end
166
230
  end
231
+
167
232
  end
168
233
 
169
234
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data.either
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jichao Ouyang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-20 00:00:00.000000000 Z
11
+ date: 2016-08-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The Either Monad
14
14
  email: oyanglulu@gmail.com