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.
- checksums.yaml +4 -4
- data/lib/control/monad.rb +5 -6
- data/lib/data.either.rb +106 -41
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c33caadee9fe0b72c04d63bb00cb0bcd6b80cbe
|
4
|
+
data.tar.gz: dcfc0d9d6ac4f8203656e9dca564ce4b0b07f230
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 '
|
13
|
+
def flat_map
|
14
|
+
raise 'flat_map No defined'
|
14
15
|
end
|
15
|
-
|
16
|
-
alias_names([:flat_map], :>=)
|
17
16
|
|
18
|
-
def
|
19
|
-
self
|
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
|
83
|
-
# if it's {Right}, pass the value to
|
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)
|
89
|
-
# expect(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)
|
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
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
list_of_either
|
138
|
-
.
|
139
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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.
|
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-
|
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
|