data.either 0.0.12 → 0.0.13
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 +4 -4
- data/lib/data.either.rb +64 -52
- data/lib/helper.rb +5 -5
- data/lib/union_type.rb +12 -12
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39e51593595d0e8af8da7020db9ae27881bc7014
|
4
|
+
data.tar.gz: dce8ad4043619d74c38bf961ef94e2d87fafafcb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd7492f59ff49e915d74aeb427755634c8b29c2d72f9d51f1c3446749511800bc61026fdbe797e23ac8ad88ba515e7b1c607d689ed7c61c5dc17daa607557a1b
|
7
|
+
data.tar.gz: bb7074754d721425749f0f11aad709096df68baec575a52ee998cea1c3f65cbb51ed111b13f03225a7ebfd8f91c911a4f0397fddcfecffadaefe6a380a832f03
|
data/lib/control/monad.rb
CHANGED
@@ -13,7 +13,7 @@ module Control
|
|
13
13
|
raise 'apply No defined'
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
module Monad
|
18
18
|
extend Helper
|
19
19
|
include Functor
|
@@ -23,9 +23,9 @@ module Control
|
|
23
23
|
end
|
24
24
|
|
25
25
|
alias_names [:bind, :chain], :flat_map
|
26
|
-
|
27
|
-
def >>
|
28
|
-
|
26
|
+
|
27
|
+
def >>(k)
|
28
|
+
flat_map { |_| k }
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/lib/data.either.rb
CHANGED
@@ -7,10 +7,25 @@ module Either
|
|
7
7
|
include Comparable
|
8
8
|
include Control::Monad
|
9
9
|
include UnionType
|
10
|
+
|
11
|
+
# try something could raise exception, and wrap value into Right, exception into Left
|
12
|
+
#
|
13
|
+
# @return [Either]
|
14
|
+
# ```ruby
|
15
|
+
# Either::try do
|
16
|
+
# something_may_raise_error
|
17
|
+
# end
|
18
|
+
# ```
|
19
|
+
def self.try
|
20
|
+
Right.new(yield)
|
21
|
+
rescue => e
|
22
|
+
Left.new(e)
|
23
|
+
end
|
24
|
+
|
10
25
|
# Either only contain one value @v
|
11
26
|
# @return [Either]
|
12
|
-
def initialize
|
13
|
-
@v=v
|
27
|
+
def initialize(v = nil)
|
28
|
+
@v = v
|
14
29
|
end
|
15
30
|
|
16
31
|
# default `false`, should override in {Left} or {Right}
|
@@ -18,6 +33,7 @@ module Either
|
|
18
33
|
def left?
|
19
34
|
false
|
20
35
|
end
|
36
|
+
|
21
37
|
# (see #left?)
|
22
38
|
def right?
|
23
39
|
false
|
@@ -28,27 +44,26 @@ module Either
|
|
28
44
|
# Right.new(1).get_or_else(2) # => 1
|
29
45
|
# Right.new(1) | 2 # => 1
|
30
46
|
# ```
|
31
|
-
def get_or_else
|
47
|
+
def get_or_else(e)
|
32
48
|
case self
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
49
|
+
when Right
|
50
|
+
@v
|
51
|
+
else
|
52
|
+
e
|
37
53
|
end
|
38
54
|
end
|
39
55
|
|
40
|
-
|
56
|
+
alias | get_or_else
|
41
57
|
|
42
|
-
def or_else
|
58
|
+
def or_else(e)
|
43
59
|
case self
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
60
|
+
when Right
|
61
|
+
|
62
|
+
else
|
63
|
+
e
|
48
64
|
end
|
49
65
|
end
|
50
66
|
|
51
|
-
|
52
67
|
# overide of Functor's `fmap`, apply function on `Right a`'s value `a`, do nothing if it's `Left e`
|
53
68
|
#
|
54
69
|
# ``` ruby
|
@@ -64,6 +79,7 @@ module Either
|
|
64
79
|
self
|
65
80
|
end
|
66
81
|
end
|
82
|
+
|
67
83
|
# the opposit of #map, apply function to `Left e`, do nothing if it's `Right a`
|
68
84
|
#
|
69
85
|
# ``` ruby
|
@@ -86,13 +102,13 @@ module Either
|
|
86
102
|
# Right.new(1).bimap ->(x){x-1}, ->(x){x+1} # => 2
|
87
103
|
# Left.new(1).bimap ->(x){x-1}, ->(x){x+1}) # => 0
|
88
104
|
# ```
|
89
|
-
# @return [Either]
|
90
|
-
def bimap
|
105
|
+
# @return [Either]
|
106
|
+
def bimap(lfn, rfn)
|
91
107
|
case self
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
108
|
+
when Right
|
109
|
+
Right.new(rfn.call(@v))
|
110
|
+
else
|
111
|
+
Left.new(lfn.call(@v))
|
96
112
|
end
|
97
113
|
end
|
98
114
|
|
@@ -131,9 +147,9 @@ module Either
|
|
131
147
|
end
|
132
148
|
end
|
133
149
|
|
134
|
-
|
135
|
-
def each
|
136
|
-
bimap(->_{}, &block)
|
150
|
+
alias swap ~@
|
151
|
+
def each(&block)
|
152
|
+
bimap(->(_) {}, &block)
|
137
153
|
end
|
138
154
|
|
139
155
|
def to_a
|
@@ -147,17 +163,17 @@ module Either
|
|
147
163
|
|
148
164
|
# comparable
|
149
165
|
# - Left < Right
|
150
|
-
def <=>
|
151
|
-
case self
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
166
|
+
def <=>(other)
|
167
|
+
other =~ case self
|
168
|
+
when Right
|
169
|
+
{ Right: ->(o) { @v <=> o },
|
170
|
+
Left: ->(_) { 1 } }
|
171
|
+
else
|
172
|
+
{ Right: ->(_) { -1 },
|
173
|
+
Left: ->(o) { @v <=> o } }
|
174
|
+
end
|
159
175
|
end
|
160
|
-
|
176
|
+
|
161
177
|
# @return [String]
|
162
178
|
def inspect
|
163
179
|
case self
|
@@ -167,7 +183,7 @@ module Either
|
|
167
183
|
"#<Right #{@v.inspect}>"
|
168
184
|
end
|
169
185
|
end
|
170
|
-
|
186
|
+
alias to_s inspect
|
171
187
|
class << self
|
172
188
|
# filter only {Right} value from List of {Either}
|
173
189
|
#
|
@@ -175,9 +191,9 @@ module Either
|
|
175
191
|
# Either.rights [Left.new(1),Right.new(5), Right.new(2)] # => [5, 2]
|
176
192
|
# ```
|
177
193
|
# @return [value]
|
178
|
-
def rights
|
194
|
+
def rights(list_of_either)
|
179
195
|
list_of_either.select(&:right?)
|
180
|
-
|
196
|
+
.map { |right| right.get_or_else(nil) }
|
181
197
|
end
|
182
198
|
|
183
199
|
# filter only {Left} value from List of {Either}
|
@@ -186,9 +202,9 @@ module Either
|
|
186
202
|
# Either.lefts [Left.new(1),Right.new(5), Right.new(2)] # => [1]
|
187
203
|
# ```
|
188
204
|
# @return [value]
|
189
|
-
def lefts
|
205
|
+
def lefts(list_of_either)
|
190
206
|
list_of_either.select(&:left?)
|
191
|
-
|
207
|
+
.map { |left| left.when(Left: ->(l) { l }) }
|
192
208
|
end
|
193
209
|
|
194
210
|
# partion a List of {Either} into a List of 2 List, one contains only {Left}, other contains only {Right}
|
@@ -197,30 +213,26 @@ module Either
|
|
197
213
|
# Either.partition [Left.new(1),Right.new(5), Right.new(2)] # => [[1],[5, 2]]
|
198
214
|
# ```
|
199
215
|
# @return [[l],[r]]
|
200
|
-
def partition
|
201
|
-
list_of_either.inject([[],[]]) do |acc, x|
|
202
|
-
x.when({
|
203
|
-
|
204
|
-
Right: ->(r){acc[1].push(r)}
|
205
|
-
})
|
216
|
+
def partition(list_of_either)
|
217
|
+
list_of_either.inject([[], []]) do |acc, x|
|
218
|
+
x.when(Left: ->(l) { acc[0].push(l) },
|
219
|
+
Right: ->(r) { acc[1].push(r) })
|
206
220
|
acc
|
207
221
|
end
|
208
222
|
end
|
209
223
|
end
|
210
|
-
|
211
224
|
end
|
212
225
|
|
213
|
-
|
214
226
|
class Left
|
215
|
-
include Either
|
227
|
+
include Either
|
216
228
|
|
217
229
|
# always true
|
218
230
|
# @return [Boolean]
|
219
231
|
def left?
|
220
232
|
true
|
221
233
|
end
|
222
|
-
|
223
|
-
def ==
|
234
|
+
|
235
|
+
def ==(other)
|
224
236
|
case other
|
225
237
|
when Left
|
226
238
|
other.left_map { |v| return v == @v }
|
@@ -232,14 +244,14 @@ end
|
|
232
244
|
|
233
245
|
class Right
|
234
246
|
include Either
|
235
|
-
|
247
|
+
|
236
248
|
# always true
|
237
249
|
# @return [Boolean]
|
238
250
|
def right?
|
239
251
|
true
|
240
252
|
end
|
241
|
-
|
242
|
-
def ==
|
253
|
+
|
254
|
+
def ==(other)
|
243
255
|
case other
|
244
256
|
when Right
|
245
257
|
other.map { |v| return v == @v }
|
data/lib/helper.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Helper
|
2
|
-
def alias_names
|
3
|
-
names.each do |name|
|
4
|
-
define_method(name) do |*args, &block|
|
5
|
-
|
2
|
+
def alias_names(names, m)
|
3
|
+
names.each do |name|
|
4
|
+
define_method(name) do |*args, &block|
|
5
|
+
send(m, *args, &block)
|
6
6
|
end
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
9
9
|
end
|
data/lib/union_type.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
require 'helper'
|
2
2
|
module UnionType
|
3
3
|
extend Helper
|
4
|
-
# similar to Scala's `match` for case class
|
5
|
-
#
|
6
|
-
# will pattern match the value out and pass to matched lambda
|
7
|
-
# ```ruby
|
8
|
-
# Right.new(1).when({Right: ->x{x+1} }) # => 2
|
9
|
-
# Right.new(1).when({Left: ->x{x+1}) # => nil
|
10
|
-
# Right.new(1) =~ ({Left: ->x{x+1}, _: ->x{x-1} }) # => 0
|
11
|
-
# ```
|
12
|
-
# @return [Either]
|
13
|
-
def when
|
4
|
+
# similar to Scala's `match` for case class
|
5
|
+
#
|
6
|
+
# will pattern match the value out and pass to matched lambda
|
7
|
+
# ```ruby
|
8
|
+
# Right.new(1).when({Right: ->x{x+1} }) # => 2
|
9
|
+
# Right.new(1).when({Left: ->x{x+1}) # => nil
|
10
|
+
# Right.new(1) =~ ({Left: ->x{x+1}, _: ->x{x-1} }) # => 0
|
11
|
+
# ```
|
12
|
+
# @return [Either]
|
13
|
+
def when(what)
|
14
14
|
current_class = self.class.to_s.to_sym
|
15
15
|
if what.include? current_class
|
16
|
-
what[current_class].(@v)
|
16
|
+
what[current_class].call(@v)
|
17
17
|
elsif what.include? :_
|
18
|
-
what[:_].(@v)
|
18
|
+
what[:_].call(@v)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|