data.either 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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