fear 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/README.md +8 -0
- data/fear.gemspec +1 -1
- data/lib/fear/either.rb +192 -97
- data/lib/fear/failure.rb +15 -7
- data/lib/fear/for.rb +22 -7
- data/lib/fear/left.rb +21 -20
- data/lib/fear/none.rb +15 -6
- data/lib/fear/option.rb +123 -40
- data/lib/fear/right.rb +25 -20
- data/lib/fear/right_biased.rb +5 -9
- data/lib/fear/some.rb +13 -8
- data/lib/fear/success.rb +16 -11
- data/lib/fear/try.rb +203 -66
- data/lib/fear/utils.rb +1 -0
- data/lib/fear/version.rb +1 -1
- data/spec/fear/failure_spec.rb +7 -1
- data/spec/fear/left_spec.rb +12 -2
- data/spec/fear/none_spec.rb +10 -7
- data/spec/fear/option_spec.rb +7 -24
- data/spec/fear/right_spec.rb +16 -2
- data/spec/fear/some_spec.rb +11 -7
- data/spec/fear/success_spec.rb +5 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b856c96f41e1cab50482a618c021f32eccd16d97
|
4
|
+
data.tar.gz: 7e443f61c506e29e1578f64e7f2237664c1465ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fef37c2dd16a69752985bd04d734ab27a69513e9db7a114c93dfb66116473d549e3a3106a0221e1f1e61ad0fa1192291cfb9e76eb7fbfc5af7297540d167610c
|
7
|
+
data.tar.gz: ff910daab541a9279e7838a971db37d9a37f6bdb220e6b17e985a9e3daaebd61cbba31167efc3e1d7b9201958310270b9788597ecc284b61f0f30bf20586e8f6
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private
|
data/README.md
CHANGED
@@ -32,6 +32,8 @@ The most idiomatic way to use an `Option` instance is to treat it
|
|
32
32
|
as a collection and use `map`, `flat_map`, `select`, or `each`:
|
33
33
|
|
34
34
|
```ruby
|
35
|
+
include Fear::Option::Mixin
|
36
|
+
|
35
37
|
name = Option(params[:name])
|
36
38
|
upper = name.map(&:strip).select { |n| n.length != 0 }.map(&:upcase)
|
37
39
|
puts upper.get_or_else('')
|
@@ -53,6 +55,8 @@ without the need to do explicit exception-handling in all of the places
|
|
53
55
|
that an exception might occur.
|
54
56
|
|
55
57
|
```ruby
|
58
|
+
include Fear::Try::Mixin
|
59
|
+
|
56
60
|
dividend = Try { Integer(params[:dividend]) }
|
57
61
|
divisor = Try { Integer(params[:divisor]) }
|
58
62
|
|
@@ -83,6 +87,8 @@ For example, you could use `Either<String, Fixnum>` to select whether a
|
|
83
87
|
received input is a `String` or an `Fixnum`.
|
84
88
|
|
85
89
|
```ruby
|
90
|
+
include Fear::Either::Mixin
|
91
|
+
|
86
92
|
input = Readline.readline('Type Either a string or an Int: ', true)
|
87
93
|
result = begin
|
88
94
|
Right(Integer(input))
|
@@ -107,6 +113,8 @@ It supports two such operations - `flat_map` and `map`. Any class providing them
|
|
107
113
|
is supported by `For`.
|
108
114
|
|
109
115
|
```ruby
|
116
|
+
include Fear::For::Mixin
|
117
|
+
|
110
118
|
For(a: Some(2), b: Some(3)) do
|
111
119
|
a * b
|
112
120
|
end #=> Some(6)
|
data/fear.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ['abolshakov@spbtv.com']
|
12
12
|
spec.summary = "%q{Ruby port of some Scala's monads.}"
|
13
13
|
spec.description = "Ruby port of some Scala's monads."
|
14
|
-
spec.homepage = 'https://github.com/bolshakov/
|
14
|
+
spec.homepage = 'https://github.com/bolshakov/fear'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0")
|
data/lib/fear/either.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Fear
|
2
2
|
# Represents a value of one of two possible types (a disjoint union.)
|
3
|
-
# An instance of
|
3
|
+
# An instance of +Either+ is either an instance of +Left+ or +Right+.
|
4
4
|
#
|
5
|
-
# A common use of
|
6
|
-
# with possible missing values. In this usage,
|
7
|
-
# with a
|
8
|
-
#
|
9
|
-
# that
|
5
|
+
# A common use of +Either+ is as an alternative to +Option+ for dealing
|
6
|
+
# with possible missing values. In this usage, +None+ is replaced
|
7
|
+
# with a +Left+ which can contain useful information.
|
8
|
+
# +Right+ takes the place of +Some+. Convention dictates
|
9
|
+
# that +Left+ is used for failure and +Right+ is used for Right.
|
10
10
|
#
|
11
|
-
# For example, you could use
|
12
|
-
# received input is a
|
11
|
+
# For example, you could use +Either<String, Fixnum>+ to select_or_else whether a
|
12
|
+
# received input is a +String+ or an +Fixnum+.
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
# in = Readline.readline('Type Either a string or an Int: ', true)
|
@@ -26,96 +26,198 @@ module Fear
|
|
26
26
|
# )
|
27
27
|
# )
|
28
28
|
#
|
29
|
-
# Either is right-biased, which means that
|
30
|
-
# operate on. If it is
|
29
|
+
# Either is right-biased, which means that +Right+ is assumed to be the default case to
|
30
|
+
# operate on. If it is +Left+, operations like +#map+, +#flat_map+, ... return the +Left+ value
|
31
31
|
# unchanged:
|
32
32
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# Right
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
# Right
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
33
|
+
# @!method get_or_else(*args)
|
34
|
+
# Returns the value from this +Right+ or evaluates the given
|
35
|
+
# default argument if this is a +Left+.
|
36
|
+
# @overload get_or_else(&default)
|
37
|
+
# @yieldreturn [any]
|
38
|
+
# @return [any]
|
39
|
+
# @example
|
40
|
+
# Right(42).get_or_else { 24/2 } #=> 42
|
41
|
+
# Left('undefined').get_or_else { 24/2 } #=> 12
|
42
|
+
# @overload get_or_else(default)
|
43
|
+
# @return [any]
|
44
|
+
# @example
|
45
|
+
# Right(42).get_or_else(12) #=> 42
|
46
|
+
# Left('undefined').get_or_else(12) #=> 12
|
47
|
+
#
|
48
|
+
# @!method include?(other_value)
|
49
|
+
# Returns +true+ if +Right+ has an element that is equal
|
50
|
+
# (as determined by +==+) to +other_value+, +false+ otherwise.
|
51
|
+
# @param [any]
|
52
|
+
# @return [Boolean]
|
53
|
+
# @example
|
54
|
+
# Right(17).include?(17) #=> true
|
55
|
+
# Right(17).include?(7) #=> false
|
56
|
+
# Left('undefined').include?(17) #=> false
|
57
|
+
#
|
58
|
+
# @!method each(&block)
|
59
|
+
# Performs the given block if this is a +Right+.
|
60
|
+
# @yieldparam [any] value
|
61
|
+
# @yieldreturn [void]
|
62
|
+
# @return [Option] itself
|
63
|
+
# @example
|
64
|
+
# Right(17).each do |value|
|
65
|
+
# puts value
|
66
|
+
# end #=> prints 17
|
67
|
+
#
|
68
|
+
# Left('undefined').each do |value|
|
69
|
+
# puts value
|
70
|
+
# end #=> does nothing
|
71
|
+
#
|
72
|
+
# @!method map(&block)
|
73
|
+
# Maps the given block to the value from this +Right+ or
|
74
|
+
# returns this if this is a +Left+.
|
75
|
+
# @yieldparam [any] value
|
76
|
+
# @yieldreturn [any]
|
77
|
+
# @example
|
78
|
+
# Right(42).map { |v| v/2 } #=> Right(21)
|
79
|
+
# Left('undefined').map { |v| v/2 } #=> Left('undefined')
|
80
|
+
#
|
81
|
+
# @!method flat_map(&block)
|
82
|
+
# Returns the given block applied to the value from this +Right+
|
83
|
+
# or returns this if this is a +Left+.
|
84
|
+
# @yieldparam [any] value
|
85
|
+
# @yieldreturn [Option]
|
86
|
+
# @return [Option]
|
87
|
+
# @example
|
88
|
+
# Right(42).flat_map { |v| Right(v/2) } #=> Right(21)
|
89
|
+
# Left('undefined').flat_map { |v| Right(v/2) } #=> Left('undefined')
|
90
|
+
#
|
91
|
+
# @!method to_a
|
92
|
+
# Returns an +Array+ containing the +Right+ value or an
|
93
|
+
# empty +Array+ if this is a +Left+.
|
94
|
+
# @return [Array]
|
95
|
+
# @example
|
96
|
+
# Right(42).to_a #=> [21]
|
97
|
+
# Left('undefined').to_a #=> []
|
98
|
+
#
|
99
|
+
# @!method to_option
|
100
|
+
# Returns an +Some+ containing the +Right+ value or a +None+ if
|
101
|
+
# this is a +Left+.
|
102
|
+
# @return [Option]
|
103
|
+
# @example
|
104
|
+
# Right(42).to_option #=> Some(21)
|
105
|
+
# Left('undefined').to_option #=> None()
|
106
|
+
#
|
107
|
+
# @!method any?(&predicate)
|
108
|
+
# Returns +false+ if +Left+ or returns the result of the
|
109
|
+
# application of the given predicate to the +Right+ value.
|
110
|
+
# @yieldparam [any] value
|
111
|
+
# @yieldreturn [Boolean]
|
112
|
+
# @return [Boolean]
|
113
|
+
# @example
|
114
|
+
# Right(12).any?( |v| v > 10) #=> true
|
115
|
+
# Right(7).any?( |v| v > 10) #=> false
|
116
|
+
# Left('undefined').any?( |v| v > 10) #=> false
|
117
|
+
#
|
118
|
+
# -----
|
119
|
+
#
|
120
|
+
# @!method right?
|
121
|
+
# Returns +true+ if this is a +Right+, +false+ otherwise.
|
122
|
+
# @note this method is also aliased as +#success?+
|
123
|
+
# @return [Boolean]
|
124
|
+
# @example
|
125
|
+
# Right(42).right? #=> true
|
126
|
+
# Left('err').right? #=> false
|
127
|
+
#
|
128
|
+
# @!method left?
|
129
|
+
# Returns +true+ if this is a +Left+, +false+ otherwise.
|
130
|
+
# @note this method is also aliased as +#failure?+
|
131
|
+
# @return [Boolean]
|
132
|
+
# @example
|
133
|
+
# Right(42).left? #=> false
|
134
|
+
# Left('err').left? #=> true
|
135
|
+
#
|
136
|
+
# @!method select_or_else(default, &predicate)
|
137
|
+
# Returns +Left+ of the default if the given predicate
|
138
|
+
# does not hold for the right value, otherwise, returns +Right+.
|
139
|
+
# @param default [Object, Proc]
|
140
|
+
# @yieldparam value [Object]
|
141
|
+
# @yieldreturn [Boolean]
|
142
|
+
# @return [Either]
|
143
|
+
# @example
|
144
|
+
# Right(12).select_or_else(-1, &:even?) #=> Right(12)
|
145
|
+
# Right(7).select_or_else(-1, &:even?) #=> Left(-1)
|
146
|
+
# Left(12).select_or_else(-1, &:even?) #=> Left(-1)
|
147
|
+
# Left(12).select_or_else(-> { -1 }, &:even?) #=> Left(-1)
|
148
|
+
#
|
149
|
+
# @!method select(&predicate)
|
150
|
+
# Returns +Left+ of value if the given predicate
|
151
|
+
# does not hold for the right value, otherwise, returns +Right+.
|
152
|
+
# @yieldparam value [Object]
|
153
|
+
# @yieldreturn [Boolean]
|
154
|
+
# @return [Either]
|
155
|
+
# @example
|
156
|
+
# Right(12).select(&:even?) #=> Right(12)
|
157
|
+
# Right(7).select(&:even?) #=> Left(7)
|
158
|
+
# Left(12).select(&:even?) #=> Left(12)
|
159
|
+
# Left(7).select(&:even?) #=> Left(7)
|
160
|
+
#
|
161
|
+
# @!method swap
|
162
|
+
# If this is a +Left+, then return the left value in +Right+ or vice versa.
|
163
|
+
# @return [Either]
|
164
|
+
# @example
|
165
|
+
# Left('left').swap #=> Right('left')
|
166
|
+
# Right('right').swap #=> Light('left')
|
167
|
+
#
|
168
|
+
# @!method reduce(reduce_left, reduce_right)
|
169
|
+
# Applies +reduce_left+ if this is a +Left+ or +reduce_right+ if
|
170
|
+
# this is a +Right+.
|
171
|
+
# @param reduce_left [Proc] the Proc to apply if this is a +Left+
|
172
|
+
# @param reduce_right [Proc] the Proc to apply if this is a +Right+
|
173
|
+
# @return [any] the results of applying the Proc
|
174
|
+
# @example
|
175
|
+
# result = possibly_failing_operation()
|
176
|
+
# log(
|
177
|
+
# result.reduce(
|
178
|
+
# ->(ex) { "Operation failed with #{ex}" },
|
179
|
+
# ->(v) { "Operation produced value: #{v}" },
|
180
|
+
# )
|
95
181
|
# )
|
96
|
-
# )
|
97
182
|
#
|
98
|
-
# @example #join_right
|
99
|
-
# Right(Right(12)).join_right #=> Right(12)
|
100
|
-
# Right(Left("flower")).join_right #=> Left("flower")
|
101
|
-
# Left("flower").join_right #=> Left("flower")
|
102
|
-
# Left(Right("flower")).join_right #=> Left(Right("flower"))
|
103
183
|
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
184
|
+
# @!method join_right
|
185
|
+
# Joins an +Either+ through +Right+. This method requires
|
186
|
+
# that the right side of this +Either+ is itself an
|
187
|
+
# +Either+ type.
|
188
|
+
# @note This method, and +join_left+, are analogous to +Option#flatten+
|
189
|
+
# @return [Either]
|
190
|
+
# @raise [TypeError] if it does not contain +Either+.
|
191
|
+
# @example
|
192
|
+
# Right(Right(12)).join_right #=> Right(12)
|
193
|
+
# Right(Left("flower")).join_right #=> Left("flower")
|
194
|
+
# Left("flower").join_right #=> Left("flower")
|
195
|
+
# Left(Right("flower")).join_right #=> Left(Right("flower"))
|
196
|
+
#
|
197
|
+
# # @!method join_right
|
198
|
+
# Joins an +Either+ through +Left+. This method requires
|
199
|
+
# that the left side of this +Either+ is itself an
|
200
|
+
# +Either+ type.
|
201
|
+
# @note This method, and +join_right+, are analogous to +Option#flatten+
|
202
|
+
# @return [Either]
|
203
|
+
# @raise [TypeError] if it does not contain +Either+.
|
204
|
+
# @example
|
205
|
+
# Left(Right("flower")).join_left #=> Right("flower")
|
206
|
+
# Left(Left(12)).join_left #=> Left(12)
|
207
|
+
# Right("daisy").join_left #=> Right("daisy")
|
208
|
+
# Right(Left("daisy")).join_left #=> Right(Left("daisy"))
|
109
209
|
#
|
110
210
|
# @see https://github.com/scala/scala/blob/2.12.x/src/library/scala/util/Either.scala
|
111
211
|
#
|
112
212
|
module Either
|
113
213
|
include Dry::Equalizer(:value)
|
114
214
|
|
215
|
+
# @private
|
115
216
|
def left_class
|
116
217
|
Left
|
117
218
|
end
|
118
219
|
|
220
|
+
# @private
|
119
221
|
def right_class
|
120
222
|
Right
|
121
223
|
end
|
@@ -124,23 +226,16 @@ module Fear
|
|
124
226
|
@value = value
|
125
227
|
end
|
126
228
|
|
127
|
-
# @return [Boolean]
|
128
|
-
def right?
|
129
|
-
is_a?(Right)
|
130
|
-
end
|
131
|
-
|
132
|
-
alias success? right?
|
133
|
-
|
134
|
-
# @return [Boolean]
|
135
|
-
def left?
|
136
|
-
!right?
|
137
|
-
end
|
138
|
-
|
139
|
-
alias failure? left?
|
140
|
-
|
141
229
|
attr_reader :value
|
142
230
|
protected :value
|
143
231
|
|
232
|
+
# Include this mixin to access convenient factory methods.
|
233
|
+
# @example
|
234
|
+
# include Fear::Either::Mixin
|
235
|
+
#
|
236
|
+
# Right('flower') #=> #<Fear::Right value='flower'>
|
237
|
+
# Left('beaf') #=> #<Fear::Legt value='beaf'>
|
238
|
+
#
|
144
239
|
module Mixin
|
145
240
|
# @param [any]
|
146
241
|
# @return [Left]
|
data/lib/fear/failure.rb
CHANGED
@@ -4,6 +4,7 @@ module Fear
|
|
4
4
|
include Dry::Equalizer(:value)
|
5
5
|
include RightBiased::Left
|
6
6
|
|
7
|
+
# @param [StandardError]
|
7
8
|
def initialize(exception)
|
8
9
|
@value = exception
|
9
10
|
end
|
@@ -11,10 +12,17 @@ module Fear
|
|
11
12
|
attr_reader :value
|
12
13
|
protected :value
|
13
14
|
|
15
|
+
# @return [Boolean]
|
14
16
|
def success?
|
15
17
|
false
|
16
18
|
end
|
17
19
|
|
20
|
+
# @return [true]
|
21
|
+
def failure?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
# @raise
|
18
26
|
def get
|
19
27
|
fail value
|
20
28
|
end
|
@@ -36,13 +44,9 @@ module Fear
|
|
36
44
|
self
|
37
45
|
end
|
38
46
|
|
39
|
-
# Applies the given block to exception.
|
40
|
-
# This is like `flat_map` for the exception.
|
41
|
-
#
|
42
47
|
# @yieldparam [Exception]
|
43
48
|
# @yieldreturn [Try]
|
44
49
|
# @return [Try]
|
45
|
-
#
|
46
50
|
def recover_with
|
47
51
|
yield(value).tap do |result|
|
48
52
|
Utils.assert_type!(result, Success, Failure)
|
@@ -51,14 +55,18 @@ module Fear
|
|
51
55
|
Failure.new(error)
|
52
56
|
end
|
53
57
|
|
54
|
-
#
|
55
|
-
#
|
58
|
+
# @yieldparam [Exception]
|
59
|
+
# @yieldreturn [any]
|
56
60
|
# @return [Try]
|
57
|
-
#
|
58
61
|
def recover
|
59
62
|
Success.new(yield(value))
|
60
63
|
rescue => error
|
61
64
|
Failure.new(error)
|
62
65
|
end
|
66
|
+
|
67
|
+
# @return [Left]
|
68
|
+
def to_either
|
69
|
+
Left.new(value)
|
70
|
+
end
|
63
71
|
end
|
64
72
|
end
|
data/lib/fear/for.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
module Fear
|
2
2
|
# This class provides syntactic sugar for composition of
|
3
3
|
# multiple monadic operations. It supports two such
|
4
|
-
# operations -
|
5
|
-
# is supported by
|
4
|
+
# operations - +flat_map+ and +map+. Any class providing them
|
5
|
+
# is supported by +For+.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
7
|
+
# For(a: Some(2), b: Some(3)) { a * b } #=> Some(6)
|
8
|
+
#
|
9
|
+
# If one of operands is None, the result is None
|
10
|
+
#
|
11
|
+
# For(a: Some(2), b: None()) { a * b } #=> None()
|
12
|
+
# For(a: None(), b: Some(2)) { a * b } #=> None()
|
12
13
|
#
|
13
14
|
# Lets look at first example:
|
14
15
|
#
|
@@ -71,6 +72,7 @@ module Fear
|
|
71
72
|
@variables = variables
|
72
73
|
end
|
73
74
|
attr_reader :variables
|
75
|
+
private :variables
|
74
76
|
|
75
77
|
def call(&block)
|
76
78
|
variable_name_and_monad, *tail = *variables
|
@@ -92,6 +94,19 @@ module Fear
|
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
97
|
+
# Include this mixin to access convenient factory method for +For+.
|
98
|
+
# @example
|
99
|
+
# include Fear::For::Mixin
|
100
|
+
#
|
101
|
+
# For(a: Some(2), b: Some(3)) { a * b } #=> Some(6)
|
102
|
+
# For(a: Some(2), b: None()) { a * b } #=> None()
|
103
|
+
#
|
104
|
+
# For(a: Right(2), b: Right(3)) { a * b } #=> Right(6)
|
105
|
+
# For(a: Right(2), b: Left(3)) { a * b } #=> Left(3)
|
106
|
+
#
|
107
|
+
# For(a: Success(2), b: Success(3)) { a * b } #=> Success(3)
|
108
|
+
# For(a: Success(2), b: Failure(...)) { a * b } #=> Failure(...)
|
109
|
+
#
|
95
110
|
module Mixin
|
96
111
|
# @param locals [Hash{Symbol => {#map, #flat_map}}]
|
97
112
|
# @return [{#map, #flat_map}]
|
data/lib/fear/left.rb
CHANGED
@@ -3,46 +3,47 @@ module Fear
|
|
3
3
|
include Either
|
4
4
|
include RightBiased::Left
|
5
5
|
|
6
|
-
#
|
7
|
-
|
6
|
+
# @return [false]
|
7
|
+
def right?
|
8
|
+
false
|
9
|
+
end
|
10
|
+
alias success? right?
|
11
|
+
|
12
|
+
# @return [true]
|
13
|
+
def left?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
alias failure? left?
|
17
|
+
|
8
18
|
# @param default [Proc, any]
|
9
19
|
# @return [Either]
|
10
|
-
|
11
|
-
def select(default)
|
20
|
+
def select_or_else(default)
|
12
21
|
Left.new(Utils.return_or_call_proc(default))
|
13
22
|
end
|
14
23
|
|
24
|
+
# @return [Left]
|
25
|
+
def select
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
15
29
|
# @return [Right] value in `Right`
|
16
|
-
#
|
17
30
|
def swap
|
18
31
|
Right.new(value)
|
19
32
|
end
|
20
33
|
|
21
|
-
# @param reduce_left [Proc]
|
22
|
-
# @return [any]
|
23
|
-
#
|
34
|
+
# @param reduce_left [Proc]
|
35
|
+
# @return [any]
|
24
36
|
def reduce(reduce_left, _)
|
25
37
|
reduce_left.call(value)
|
26
38
|
end
|
27
39
|
|
28
|
-
# Joins an `Either` through `Right`.
|
29
|
-
#
|
30
40
|
# @return [self]
|
31
|
-
#
|
32
41
|
def join_right
|
33
42
|
self
|
34
43
|
end
|
35
44
|
|
36
|
-
# Joins an `Either` through `Left`.
|
37
|
-
#
|
38
|
-
# This method requires that the left side of this `Either` is itself an
|
39
|
-
# Either type.
|
40
|
-
#
|
41
|
-
# This method, and `join_right`, are analogous to `Option#flatten`
|
42
|
-
#
|
43
45
|
# @return [Either]
|
44
|
-
# @raise [TypeError]
|
45
|
-
#
|
46
|
+
# @raise [TypeError]
|
46
47
|
def join_left
|
47
48
|
value.tap do |v|
|
48
49
|
Utils.assert_type!(v, Either)
|
data/lib/fear/none.rb
CHANGED
@@ -4,18 +4,27 @@ module Fear
|
|
4
4
|
include Dry::Equalizer()
|
5
5
|
include RightBiased::Left
|
6
6
|
|
7
|
-
#
|
8
|
-
|
7
|
+
# @raise [NoSuchElementError]
|
8
|
+
def get
|
9
|
+
fail NoSuchElementError
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [nil]
|
13
|
+
def or_nil
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [true]
|
18
|
+
def empty?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
9
22
|
# @return [None]
|
10
|
-
#
|
11
23
|
def select(*)
|
12
24
|
self
|
13
25
|
end
|
14
26
|
|
15
|
-
# Ignores the given block and return self.
|
16
|
-
#
|
17
27
|
# @return [None]
|
18
|
-
#
|
19
28
|
def reject(*)
|
20
29
|
self
|
21
30
|
end
|