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.
- 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
|