fear 2.0.1 → 3.1.0
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/.github/workflows/ci.yml +105 -0
- data/.simplecov +2 -2
- data/.standard.yml +1 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +14 -2
- data/Gemfile.lock +84 -78
- data/LICENSE.txt +1 -1
- data/README.md +18 -70
- data/Rakefile +55 -142
- data/benchmarks/dry_do_vs_fear_for.txt +7 -6
- data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +7 -6
- data/benchmarks/factorial.txt +7 -9
- data/benchmarks/fear_gaurd_and1_vs_new.txt +7 -6
- data/benchmarks/fear_gaurd_and2_vs_and.txt +8 -7
- data/benchmarks/fear_gaurd_and3_vs_and_and.txt +7 -6
- data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +7 -6
- data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +8 -10
- data/examples/pattern_extracting.rb +2 -2
- data/examples/pattern_matching_number_in_words.rb +12 -12
- data/fear.gemspec +5 -21
- data/lib/fear/either/left_projection.rb +237 -0
- data/lib/fear/either/pattern_match.rb +49 -0
- data/lib/fear/either.rb +21 -12
- data/lib/fear/either_api.rb +2 -4
- data/lib/fear/empty_partial_function.rb +3 -3
- data/lib/fear/failure/pattern_match.rb +14 -0
- data/lib/fear/failure.rb +5 -5
- data/lib/fear/for.rb +1 -1
- data/lib/fear/for_api.rb +1 -3
- data/lib/fear/future.rb +6 -6
- data/lib/fear/future_api.rb +0 -5
- data/lib/fear/left/pattern_match.rb +15 -0
- data/lib/fear/left.rb +4 -4
- data/lib/fear/none.rb +0 -87
- data/lib/fear/none_class/pattern_match.rb +16 -0
- data/lib/fear/none_class.rb +85 -0
- data/lib/fear/option/pattern_match.rb +47 -0
- data/lib/fear/option.rb +2 -6
- data/lib/fear/option_api.rb +1 -3
- data/lib/fear/partial_function/and_then.rb +2 -2
- data/lib/fear/partial_function/combined.rb +3 -3
- data/lib/fear/partial_function/empty.rb +3 -5
- data/lib/fear/partial_function/guard.rb +0 -4
- data/lib/fear/partial_function/or_else.rb +2 -4
- data/lib/fear/partial_function.rb +0 -9
- data/lib/fear/partial_function_class.rb +2 -2
- data/lib/fear/pattern_match.rb +5 -4
- data/lib/fear/pattern_matching_api.rb +1 -4
- data/lib/fear/right/pattern_match.rb +15 -0
- data/lib/fear/right.rb +4 -4
- data/lib/fear/right_biased.rb +2 -0
- data/lib/fear/some/pattern_match.rb +15 -0
- data/lib/fear/some.rb +3 -3
- data/lib/fear/success/pattern_match.rb +16 -0
- data/lib/fear/success.rb +5 -5
- data/lib/fear/try/pattern_match.rb +29 -0
- data/lib/fear/try.rb +3 -7
- data/lib/fear/try_api.rb +1 -3
- data/lib/fear/utils.rb +1 -1
- data/lib/fear/version.rb +1 -1
- data/lib/fear.rb +3 -14
- data/spec/fear/awaitable_spec.rb +0 -2
- data/spec/fear/either/left_projection_spec.rb +289 -0
- data/spec/fear/{either_pattern_match_spec.rb → either/pattern_match_spec.rb} +7 -7
- data/spec/fear/either_spec.rb +1 -1
- data/spec/fear/left_spec.rb +1 -1
- data/spec/fear/{option_pattern_match_spec.rb → option/pattern_match_spec.rb} +6 -6
- data/spec/fear/option_spec.rb +2 -2
- data/spec/fear/partial_function/any_spec.rb +3 -3
- data/spec/fear/partial_function/empty_spec.rb +2 -2
- data/spec/fear/partial_function_and_then_spec.rb +5 -5
- data/spec/fear/partial_function_composition_spec.rb +6 -6
- data/spec/fear/partial_function_or_else_spec.rb +13 -13
- data/spec/fear/partial_function_spec.rb +7 -7
- data/spec/fear/pattern_match_spec.rb +5 -5
- data/spec/fear/right_spec.rb +1 -1
- data/spec/fear/{try_pattern_match_spec.rb → try/try_pattern_match_spec.rb} +7 -7
- data/spec/fear/try_api_spec.rb +2 -2
- data/spec/fear/utils_spec.rb +3 -3
- data/spec/support/.keep +0 -0
- metadata +27 -296
- data/.github/workflows/rubocop.yml +0 -39
- data/.github/workflows/spec.yml +0 -43
- data/.rubocop.yml +0 -7
- data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +0 -11
- data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +0 -11
- data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +0 -11
- data/lib/dry/types/fear/option.rb +0 -125
- data/lib/dry/types/fear.rb +0 -8
- data/lib/fear/either_pattern_match.rb +0 -52
- data/lib/fear/failure_pattern_match.rb +0 -12
- data/lib/fear/left_pattern_match.rb +0 -11
- data/lib/fear/none_pattern_match.rb +0 -14
- data/lib/fear/option_pattern_match.rb +0 -50
- data/lib/fear/right_pattern_match.rb +0 -13
- data/lib/fear/some_pattern_match.rb +0 -13
- data/lib/fear/struct.rb +0 -237
- data/lib/fear/success_pattern_match.rb +0 -14
- data/lib/fear/try_pattern_match.rb +0 -32
- data/spec/dry/types/fear/option/constrained_spec.rb +0 -22
- data/spec/dry/types/fear/option/core_spec.rb +0 -77
- data/spec/dry/types/fear/option/default_spec.rb +0 -21
- data/spec/dry/types/fear/option/hash_spec.rb +0 -58
- data/spec/dry/types/fear/option/option_spec.rb +0 -97
- data/spec/struct_pattern_matching_spec.rb +0 -36
- data/spec/struct_spec.rb +0 -194
- data/spec/support/dry_types.rb +0 -6
@@ -0,0 +1,237 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fear
|
4
|
+
module Either
|
5
|
+
# Projects an `Either` into a `Left`.
|
6
|
+
# @see Fear::Either#left
|
7
|
+
#
|
8
|
+
class LeftProjection
|
9
|
+
prepend Fear::RightBiased::Interface
|
10
|
+
|
11
|
+
# @!attribute either
|
12
|
+
# @return [Fear::Either]
|
13
|
+
attr_reader :either
|
14
|
+
protected :either
|
15
|
+
|
16
|
+
# @param either [Fear::Either]
|
17
|
+
def initialize(either)
|
18
|
+
@either = either
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns +true+ if +Fear::Left+ has an element that is equal
|
22
|
+
# (as determined by +==+) to +other_value+, +false+ otherwise.
|
23
|
+
# @param [Object]
|
24
|
+
# @return [Boolean]
|
25
|
+
# @example
|
26
|
+
# Fear.left(17).left.include?(17) #=> true
|
27
|
+
# Fear.left(17).left.include?(7) #=> false
|
28
|
+
# Fear.right('undefined').left.include?(17) #=> false
|
29
|
+
#
|
30
|
+
def include?(other_value)
|
31
|
+
case either
|
32
|
+
in Fear::Left(x)
|
33
|
+
x == other_value
|
34
|
+
in Fear::Right
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the value from this +Fear::Left+ or evaluates the given
|
40
|
+
# default argument if this is a +Fear::Right+.
|
41
|
+
#
|
42
|
+
# @overload get_or_else(&default)
|
43
|
+
# @yieldreturn [Object]
|
44
|
+
# @return [Object]
|
45
|
+
# @example
|
46
|
+
# Fear.right(42).left.get_or_else { 24/2 } #=> 12
|
47
|
+
# Fear.left('undefined').left.get_or_else { 24/2 } #=> 'undefined'
|
48
|
+
#
|
49
|
+
# @overload get_or_else(default)
|
50
|
+
# @return [Object]
|
51
|
+
# @example
|
52
|
+
# Fear.right(42).left.get_or_else(12) #=> 12
|
53
|
+
# Fear.left('undefined').left.get_or_else(12) #=> 'undefined'
|
54
|
+
def get_or_else(*args)
|
55
|
+
case either
|
56
|
+
in Fear::Left(value)
|
57
|
+
value
|
58
|
+
in Fear::Right
|
59
|
+
args.fetch(0) { yield }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Performs the given block if this is a +Fear::Left+.
|
64
|
+
#
|
65
|
+
# @yieldparam [Object] value
|
66
|
+
# @yieldreturn [void]
|
67
|
+
# @return [Fear::Either] itself
|
68
|
+
# @example
|
69
|
+
# Fear.right(17).left.each do |value|
|
70
|
+
# puts value
|
71
|
+
# end #=> does nothing
|
72
|
+
#
|
73
|
+
# Fear.left('undefined').left.each do |value|
|
74
|
+
# puts value
|
75
|
+
# end #=> prints "nothing"
|
76
|
+
def each
|
77
|
+
case either
|
78
|
+
in Fear::Left(value)
|
79
|
+
yield(value)
|
80
|
+
either
|
81
|
+
in Fear::Right
|
82
|
+
either
|
83
|
+
end
|
84
|
+
end
|
85
|
+
alias_method :apply, :each
|
86
|
+
|
87
|
+
# Maps the block argument through +Fear::Left+.
|
88
|
+
#
|
89
|
+
# @yieldparam [Object] value
|
90
|
+
# @yieldreturn [Fear::Either]
|
91
|
+
# @example
|
92
|
+
# Fear.left(42).left.map { _1/2 } #=> Fear.left(24)
|
93
|
+
# Fear.right(42).left.map { _1/2 } #=> Fear.right(42)
|
94
|
+
#
|
95
|
+
def map
|
96
|
+
case either
|
97
|
+
in Fear::Left(value)
|
98
|
+
Fear.left(yield(value))
|
99
|
+
in Fear::Right
|
100
|
+
either
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns the given block applied to the value from this +Fear::Left+
|
105
|
+
# or returns this if this is a +Fear::Right+.
|
106
|
+
#
|
107
|
+
# @yieldparam [Object] value
|
108
|
+
# @yieldreturn [Fear::Either]
|
109
|
+
# @return [Fear::Either]
|
110
|
+
#
|
111
|
+
# @example
|
112
|
+
# Fear.left(12).left.flat_map { Fear.left(_1 * 2) } #=> Fear.left(24)
|
113
|
+
# Fear.left(12).left.flat_map { Fear.right(_1 * 2) } #=> Fear.right(24)
|
114
|
+
# Fear.right(12).left.flat_map { Fear.left(_1 * 2) } #=> Fear.right(12)
|
115
|
+
#
|
116
|
+
def flat_map
|
117
|
+
case either
|
118
|
+
in Fear::Left(value)
|
119
|
+
yield(value)
|
120
|
+
in Fear::Right
|
121
|
+
either
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns an +Fear::Some+ containing the +Fear::Left+ value or a +Fear::None+ if
|
126
|
+
# this is a +Fear::Right+.
|
127
|
+
# @return [Fear::Option]
|
128
|
+
# @example
|
129
|
+
# Fear.left(42).left.to_option #=> Fear.some(42)
|
130
|
+
# Fear.right(42).left.to_option #=> Fear.none
|
131
|
+
#
|
132
|
+
def to_option
|
133
|
+
case either
|
134
|
+
in Fear::Left(value)
|
135
|
+
Fear.some(value)
|
136
|
+
in Fear::Right
|
137
|
+
Fear.none
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns an array containing the +Fear::Left+ value or an empty array if
|
142
|
+
# this is a +Fear::Right+.
|
143
|
+
#
|
144
|
+
# @return [Array]
|
145
|
+
# @example
|
146
|
+
# Fear.left(42).left.to_a #=> [42]
|
147
|
+
# Fear.right(42).left.to_a #=> []
|
148
|
+
#
|
149
|
+
def to_a
|
150
|
+
case either
|
151
|
+
in Fear::Left(value)
|
152
|
+
[value]
|
153
|
+
in Fear::Right
|
154
|
+
[]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns +false+ if +Fear::Right+ or returns the result of the
|
159
|
+
# application of the given predicate to the +Fear::Light+ value.
|
160
|
+
#
|
161
|
+
# @yieldparam [Object] value
|
162
|
+
# @yieldreturn [Boolean]
|
163
|
+
# @return [Boolean]
|
164
|
+
# @example
|
165
|
+
# Fear.left(12).left.any? { |v| v > 10 } #=> true
|
166
|
+
# Fear.left(7).left.any? { |v| v > 10 } #=> false
|
167
|
+
# Fear.right(12).left.any? { |v| v > 10 } #=> false
|
168
|
+
#
|
169
|
+
def any?(&predicate)
|
170
|
+
case either
|
171
|
+
in Fear::Left(value)
|
172
|
+
predicate.call(value)
|
173
|
+
in Fear::Right
|
174
|
+
false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Returns +Fear::Right+ of value if the given predicate
|
179
|
+
# does not hold for the left value, otherwise, returns +Fear::Left+.
|
180
|
+
#
|
181
|
+
# @yieldparam value [Object]
|
182
|
+
# @yieldreturn [Boolean]
|
183
|
+
# @return [Fear::Either]
|
184
|
+
# @example
|
185
|
+
# Fear.left(12).left.select(&:even?) #=> Fear.left(12)
|
186
|
+
# Fear.left(7).left.select(&:even?) #=> Fear.right(7)
|
187
|
+
# Fear.right(12).left.select(&:even?) #=> Fear.right(12)
|
188
|
+
# Fear.right(7).left.select(&:even?) #=> Fear.right(7)
|
189
|
+
#
|
190
|
+
def select(&predicate)
|
191
|
+
case either
|
192
|
+
in Fear::Right
|
193
|
+
either
|
194
|
+
in Fear::Left(value) if predicate.call(value)
|
195
|
+
either
|
196
|
+
in Fear::Left
|
197
|
+
either.swap
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns +Fear::None+ if this is a +Fear::Right+ or if the given predicate
|
202
|
+
# does not hold for the left value, otherwise, returns a +Fear::Left+.
|
203
|
+
#
|
204
|
+
# @yieldparam value [Object]
|
205
|
+
# @yieldreturn [Boolean]
|
206
|
+
# @return [Fear::Option<Fear::Either>]
|
207
|
+
# @example
|
208
|
+
# Fear.left(12).left.find(&:even?) #=> #<Fear::Some value=#<Fear::Left value=12>>
|
209
|
+
# Fear.left(7).left.find(&:even?) #=> #<Fear::None>
|
210
|
+
# Fear.right(12).left.find(&:even) #=> #<Fear::None>
|
211
|
+
#
|
212
|
+
def find(&predicate)
|
213
|
+
case either
|
214
|
+
in Fear::Left(value) if predicate.call(value)
|
215
|
+
Fear.some(either)
|
216
|
+
in Fear::Either
|
217
|
+
Fear.none
|
218
|
+
end
|
219
|
+
end
|
220
|
+
alias_method :detect, :find
|
221
|
+
|
222
|
+
# @param other [Object]
|
223
|
+
# @return [Boolean]
|
224
|
+
def ==(other)
|
225
|
+
other.is_a?(self.class) && other.either == either
|
226
|
+
end
|
227
|
+
|
228
|
+
private def left_class
|
229
|
+
Fear::Right
|
230
|
+
end
|
231
|
+
|
232
|
+
private def right_class
|
233
|
+
Fear::Left
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fear
|
4
|
+
module Either
|
5
|
+
# Either pattern matcher
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# pattern_match =
|
9
|
+
# EitherPatternMatch.new
|
10
|
+
# .right(Integer, ->(x) { x > 2 }) { |x| x * 2 }
|
11
|
+
# .right(String) { |x| x.to_i * 2 }
|
12
|
+
# .left(String) { :err }
|
13
|
+
# .else { 'error '}
|
14
|
+
#
|
15
|
+
# pattern_match.call(42) => 'NaN'
|
16
|
+
#
|
17
|
+
# @example the same matcher may be defined using block syntax
|
18
|
+
# EitherPatternMatch.new do |m|
|
19
|
+
# m.right(Integer, ->(x) { x > 2 }) { |x| x * 2 }
|
20
|
+
# m.right(String) { |x| x.to_i * 2 }
|
21
|
+
# m.left(String) { :err }
|
22
|
+
# m.else { 'error '}
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @note it has two optimized subclasses +Fear::Left::PatternMatch+ and +Fear::Right::PatternMatch+
|
26
|
+
# @api private
|
27
|
+
class PatternMatch < Fear::PatternMatch
|
28
|
+
# Match against +Fear::Right+
|
29
|
+
#
|
30
|
+
# @param conditions [<#==>]
|
31
|
+
# @return [Fear::Either::PatternMatch]
|
32
|
+
def right(*conditions, &effect)
|
33
|
+
branch = Fear.case(Fear::Right, &:right_value).and_then(Fear.case(*conditions, &effect))
|
34
|
+
or_else(branch)
|
35
|
+
end
|
36
|
+
alias_method :success, :right
|
37
|
+
|
38
|
+
# Match against +Fear::Left+
|
39
|
+
#
|
40
|
+
# @param conditions [<#==>]
|
41
|
+
# @return [Fear::Either::PatternMatch]
|
42
|
+
def left(*conditions, &effect)
|
43
|
+
branch = Fear.case(Fear::Left, &:left_value).and_then(Fear.case(*conditions, &effect))
|
44
|
+
or_else(branch)
|
45
|
+
end
|
46
|
+
alias_method :failure, :left
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/fear/either.rb
CHANGED
@@ -116,9 +116,9 @@ module Fear
|
|
116
116
|
# @yieldreturn [Boolean]
|
117
117
|
# @return [Boolean]
|
118
118
|
# @example
|
119
|
-
# Fear.right(12).any?
|
120
|
-
# Fear.right(7).any?
|
121
|
-
# Fear.left('undefined').any?
|
119
|
+
# Fear.right(12).any? { |v| v > 10 } #=> true
|
120
|
+
# Fear.right(7).any? { |v| v > 10 } #=> false
|
121
|
+
# Fear.left('undefined').any? { |v| v > 10 } #=> false
|
122
122
|
#
|
123
123
|
# -----
|
124
124
|
#
|
@@ -177,7 +177,7 @@ module Fear
|
|
177
177
|
#
|
178
178
|
# @!method swap
|
179
179
|
# If this is a +Left+, then return the left value in +Right+ or vice versa.
|
180
|
-
# @return [Either]
|
180
|
+
# @return [Fear::Either]
|
181
181
|
# @example
|
182
182
|
# Fear.left('left').swap #=> Fear.right('left')
|
183
183
|
# Fear.right('right').swap #=> Fear.left('left')
|
@@ -226,7 +226,7 @@ module Fear
|
|
226
226
|
#
|
227
227
|
# @!method match(&matcher)
|
228
228
|
# Pattern match against this +Either+
|
229
|
-
# @yield matcher [Fear::
|
229
|
+
# @yield matcher [Fear::Either::PatternMatch]
|
230
230
|
# @example
|
231
231
|
# either.match do |m|
|
232
232
|
# m.right(Integer) do |x|
|
@@ -273,13 +273,26 @@ module Fear
|
|
273
273
|
end
|
274
274
|
|
275
275
|
# @return [String]
|
276
|
-
|
276
|
+
alias_method :to_s, :inspect
|
277
277
|
|
278
278
|
# @return [<any>]
|
279
279
|
def deconstruct
|
280
280
|
[value]
|
281
281
|
end
|
282
282
|
|
283
|
+
# Projects this +Fear::Either+ as a +Fear::Left+.
|
284
|
+
# This allows performing right-biased operation of the left
|
285
|
+
# side of the +Fear::Either+.
|
286
|
+
#
|
287
|
+
# @example
|
288
|
+
# Fear.left(42).left.map(&:succ) #=> Fear.left(43)
|
289
|
+
# Fear.right(42).left.map(&:succ) #=> Fear.left(42)
|
290
|
+
#
|
291
|
+
# @return [Fear::LeftProjection]
|
292
|
+
def left
|
293
|
+
LeftProjection.new(self)
|
294
|
+
end
|
295
|
+
|
283
296
|
class << self
|
284
297
|
# Build pattern matcher to be used later, despite off
|
285
298
|
# +Either#match+ method, id doesn't apply matcher immanently,
|
@@ -296,10 +309,10 @@ module Fear
|
|
296
309
|
# end
|
297
310
|
# matcher.call(Fear.right(42))
|
298
311
|
#
|
299
|
-
# @yieldparam [Fear::
|
312
|
+
# @yieldparam [Fear::Either::PatternMatch]
|
300
313
|
# @return [Fear::PartialFunction]
|
301
314
|
def matcher(&matcher)
|
302
|
-
|
315
|
+
Either::PatternMatch.new(&matcher)
|
303
316
|
end
|
304
317
|
end
|
305
318
|
|
@@ -331,7 +344,3 @@ module Fear
|
|
331
344
|
end
|
332
345
|
end
|
333
346
|
end
|
334
|
-
|
335
|
-
require "fear/either_pattern_match"
|
336
|
-
require "fear/left"
|
337
|
-
require "fear/right"
|
data/lib/fear/either_api.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "fear/either"
|
4
|
-
|
5
3
|
module Fear
|
6
4
|
module EitherApi
|
7
|
-
# @param value [
|
5
|
+
# @param value [Object]
|
8
6
|
# @return [Fear::Left]
|
9
7
|
# @example
|
10
8
|
# Fear.left(42) #=> #<Fear::Left value=42>
|
@@ -13,7 +11,7 @@ module Fear
|
|
13
11
|
Fear::Left.new(value)
|
14
12
|
end
|
15
13
|
|
16
|
-
# @param value [
|
14
|
+
# @param value [Object]
|
17
15
|
# @return [Fear::Right]
|
18
16
|
# @example
|
19
17
|
# Fear.right(42) #=> #<Fear::Right value=42>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Fear
|
4
|
-
# Use singleton version of EmptyPartialFunction -- PartialFunction::
|
4
|
+
# Use singleton version of EmptyPartialFunction -- PartialFunction::Empty
|
5
5
|
# @api private
|
6
6
|
class EmptyPartialFunction
|
7
7
|
include PartialFunction
|
@@ -14,8 +14,8 @@ module Fear
|
|
14
14
|
raise MatchError, "partial function not defined at: #{arg}"
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
alias_method :===, :call
|
18
|
+
alias_method :[], :call
|
19
19
|
|
20
20
|
def call_or_else(arg)
|
21
21
|
yield arg
|
data/lib/fear/failure.rb
CHANGED
@@ -4,7 +4,7 @@ module Fear
|
|
4
4
|
class Failure
|
5
5
|
include Try
|
6
6
|
include RightBiased::Left
|
7
|
-
include
|
7
|
+
include PatternMatch.mixin
|
8
8
|
|
9
9
|
# @param [StandardError]
|
10
10
|
def initialize(exception)
|
@@ -31,7 +31,7 @@ module Fear
|
|
31
31
|
# @return [Try] of calling block
|
32
32
|
def or_else(*args)
|
33
33
|
super
|
34
|
-
rescue
|
34
|
+
rescue => error
|
35
35
|
Failure.new(error)
|
36
36
|
end
|
37
37
|
|
@@ -52,7 +52,7 @@ module Fear
|
|
52
52
|
Fear.matcher { |m| yield(m) }
|
53
53
|
.and_then { |result| result.tap { Utils.assert_type!(result, Success, Failure) } }
|
54
54
|
.call_or_else(exception) { self }
|
55
|
-
rescue
|
55
|
+
rescue => error
|
56
56
|
Failure.new(error)
|
57
57
|
end
|
58
58
|
|
@@ -63,7 +63,7 @@ module Fear
|
|
63
63
|
Fear.matcher { |m| yield(m) }
|
64
64
|
.and_then { |v| Success.new(v) }
|
65
65
|
.call_or_else(exception) { self }
|
66
|
-
rescue
|
66
|
+
rescue => error
|
67
67
|
Failure.new(error)
|
68
68
|
end
|
69
69
|
|
@@ -95,7 +95,7 @@ module Fear
|
|
95
95
|
end
|
96
96
|
|
97
97
|
# @return [String]
|
98
|
-
|
98
|
+
alias_method :to_s, :inspect
|
99
99
|
|
100
100
|
# @return [<StandardError>]
|
101
101
|
def deconstruct
|
data/lib/fear/for.rb
CHANGED
data/lib/fear/for_api.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "fear/for"
|
4
|
-
|
5
3
|
module Fear
|
6
4
|
module ForApi
|
7
5
|
# Syntactic sugar for composition of multiple monadic operations. It supports two such
|
@@ -64,7 +62,7 @@ module Fear
|
|
64
62
|
# @return [{#map, #flat_map}]
|
65
63
|
#
|
66
64
|
def for(*monads, &block)
|
67
|
-
Fear::For.(monads, &block)
|
65
|
+
Fear::For.call(monads, &block)
|
68
66
|
end
|
69
67
|
end
|
70
68
|
end
|
data/lib/fear/future.rb
CHANGED
@@ -170,7 +170,7 @@ module Fear
|
|
170
170
|
#
|
171
171
|
# If the future has already been completed,
|
172
172
|
# this will either be applied immediately or be scheduled asynchronously.
|
173
|
-
# @yieldparam [Fear::
|
173
|
+
# @yieldparam [Fear::Try::PatternMatch]
|
174
174
|
# @return [self]
|
175
175
|
#
|
176
176
|
# @example
|
@@ -221,7 +221,7 @@ module Fear
|
|
221
221
|
# @yieldparam [any] yields with successful feature value
|
222
222
|
# @see {#on_complete}
|
223
223
|
#
|
224
|
-
|
224
|
+
alias_method :each, :on_success
|
225
225
|
|
226
226
|
# Creates a new future by applying the +success+ function to the successful
|
227
227
|
# result of this future, or the +failure+ function to the failed result.
|
@@ -245,8 +245,8 @@ module Fear
|
|
245
245
|
def transform(success, failure)
|
246
246
|
promise = Promise.new(**@options)
|
247
247
|
on_complete_match do |m|
|
248
|
-
m.success { |value| promise.success(success.(value)) }
|
249
|
-
m.failure { |error| promise.failure(failure.(error)) }
|
248
|
+
m.success { |value| promise.success(success.call(value)) }
|
249
|
+
m.failure { |error| promise.failure(failure.call(error)) }
|
250
250
|
end
|
251
251
|
promise.to_future
|
252
252
|
end
|
@@ -293,7 +293,7 @@ module Fear
|
|
293
293
|
m.case(Fear::Failure) { |failure| promise.complete!(failure) }
|
294
294
|
m.success do |value|
|
295
295
|
yield(value).on_complete { |callback_result| promise.complete!(callback_result) }
|
296
|
-
rescue
|
296
|
+
rescue => error
|
297
297
|
promise.failure!(error)
|
298
298
|
end
|
299
299
|
end
|
@@ -379,7 +379,7 @@ module Fear
|
|
379
379
|
else
|
380
380
|
[value, other_value]
|
381
381
|
end
|
382
|
-
end
|
382
|
+
end
|
383
383
|
)
|
384
384
|
end
|
385
385
|
end
|
data/lib/fear/future_api.rb
CHANGED
@@ -6,11 +6,6 @@ rescue LoadError
|
|
6
6
|
puts "You must add 'concurrent-ruby' to your Gemfile in order to use Fear::Future"
|
7
7
|
end
|
8
8
|
|
9
|
-
require "fear/awaitable"
|
10
|
-
require "fear/await"
|
11
|
-
require "fear/future"
|
12
|
-
require "fear/promise"
|
13
|
-
|
14
9
|
module Fear
|
15
10
|
# rubocop: disable Layout/LineLength
|
16
11
|
module FutureApi
|
data/lib/fear/left.rb
CHANGED
@@ -4,7 +4,7 @@ module Fear
|
|
4
4
|
class Left
|
5
5
|
include Either
|
6
6
|
include RightBiased::Left
|
7
|
-
include
|
7
|
+
include PatternMatch.mixin
|
8
8
|
|
9
9
|
# @api private
|
10
10
|
def left_value
|
@@ -15,13 +15,13 @@ module Fear
|
|
15
15
|
def right?
|
16
16
|
false
|
17
17
|
end
|
18
|
-
|
18
|
+
alias_method :success?, :right?
|
19
19
|
|
20
20
|
# @return [true]
|
21
21
|
def left?
|
22
22
|
true
|
23
23
|
end
|
24
|
-
|
24
|
+
alias_method :failure?, :left?
|
25
25
|
|
26
26
|
# @return [Either]
|
27
27
|
def select_or_else(*)
|
@@ -46,7 +46,7 @@ module Fear
|
|
46
46
|
# @param reduce_left [Proc]
|
47
47
|
# @return [any]
|
48
48
|
def reduce(reduce_left, _reduce_right)
|
49
|
-
reduce_left.(value)
|
49
|
+
reduce_left.call(value)
|
50
50
|
end
|
51
51
|
|
52
52
|
# @return [self]
|
data/lib/fear/none.rb
CHANGED
@@ -1,94 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Fear
|
4
|
-
# @api private
|
5
|
-
class NoneClass
|
6
|
-
include Option
|
7
|
-
include RightBiased::Left
|
8
|
-
include NonePatternMatch.mixin
|
9
|
-
|
10
|
-
# @raise [NoSuchElementError]
|
11
|
-
def get
|
12
|
-
raise NoSuchElementError
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [nil]
|
16
|
-
def or_nil
|
17
|
-
nil
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [true]
|
21
|
-
def empty?
|
22
|
-
true
|
23
|
-
end
|
24
|
-
|
25
|
-
alias :blank? :empty?
|
26
|
-
|
27
|
-
# @return [false]
|
28
|
-
def present?
|
29
|
-
false
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [None]
|
33
|
-
def select(*)
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
# @return [None]
|
38
|
-
def reject(*)
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
# @return [String]
|
43
|
-
def inspect
|
44
|
-
"#<Fear::NoneClass>"
|
45
|
-
end
|
46
|
-
|
47
|
-
# @return [String]
|
48
|
-
alias to_s inspect
|
49
|
-
|
50
|
-
# @param other [Any]
|
51
|
-
# @return [Boolean]
|
52
|
-
def ==(other)
|
53
|
-
other.is_a?(NoneClass)
|
54
|
-
end
|
55
|
-
|
56
|
-
# @param other
|
57
|
-
# @return [Boolean]
|
58
|
-
def ===(other)
|
59
|
-
self == other
|
60
|
-
end
|
61
|
-
|
62
|
-
# @param other [Fear::Option]
|
63
|
-
# @return [Fear::Option]
|
64
|
-
def zip(other)
|
65
|
-
if other.is_a?(Option)
|
66
|
-
Fear.none
|
67
|
-
else
|
68
|
-
raise TypeError, "can't zip with #{other.class}"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# @return [RightBiased::Left]
|
73
|
-
def filter_map
|
74
|
-
self
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
private_constant(:NoneClass)
|
79
|
-
|
80
4
|
# The only instance of NoneClass
|
81
|
-
# @api private
|
82
5
|
None = NoneClass.new.freeze
|
83
6
|
public_constant :None
|
84
|
-
|
85
|
-
class << NoneClass
|
86
|
-
def new
|
87
|
-
None
|
88
|
-
end
|
89
|
-
|
90
|
-
def inherited(*)
|
91
|
-
raise "you are not allowed to inherit from NoneClass, use Fear::None instead"
|
92
|
-
end
|
93
|
-
end
|
94
7
|
end
|