fear 0.11.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +18 -0
  4. data/.travis.yml +0 -3
  5. data/CHANGELOG.md +12 -1
  6. data/Gemfile +1 -0
  7. data/{gemfiles/dry_equalizer_0.2.1.gemfile.lock → Gemfile.lock} +21 -12
  8. data/README.md +594 -241
  9. data/Rakefile +166 -219
  10. data/benchmarks/README.md +1 -0
  11. data/benchmarks/dry_do_vs_fear_for.txt +11 -0
  12. data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +11 -0
  13. data/benchmarks/factorial.txt +16 -0
  14. data/benchmarks/fear_gaurd_and1_vs_new.txt +13 -0
  15. data/benchmarks/fear_gaurd_and2_vs_and.txt +13 -0
  16. data/benchmarks/fear_gaurd_and3_vs_and_and.txt +13 -0
  17. data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +11 -0
  18. data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +13 -0
  19. data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +14 -0
  20. data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +11 -0
  21. data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +11 -0
  22. data/examples/pattern_extracting.rb +15 -0
  23. data/examples/pattern_matching_binary_tree_set.rb +96 -0
  24. data/examples/pattern_matching_number_in_words.rb +54 -0
  25. data/fear.gemspec +4 -2
  26. data/lib/fear.rb +21 -4
  27. data/lib/fear/either.rb +77 -59
  28. data/lib/fear/either_api.rb +21 -0
  29. data/lib/fear/empty_partial_function.rb +1 -1
  30. data/lib/fear/extractor.rb +108 -0
  31. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +8 -0
  32. data/lib/fear/extractor/any_matcher.rb +15 -0
  33. data/lib/fear/extractor/array_head_matcher.rb +34 -0
  34. data/lib/fear/extractor/array_matcher.rb +38 -0
  35. data/lib/fear/extractor/array_splat_matcher.rb +14 -0
  36. data/lib/fear/extractor/empty_list_matcher.rb +18 -0
  37. data/lib/fear/extractor/extractor_matcher.rb +42 -0
  38. data/lib/fear/extractor/grammar.rb +201 -0
  39. data/lib/fear/extractor/grammar.treetop +129 -0
  40. data/lib/fear/extractor/identifier_matcher.rb +16 -0
  41. data/lib/fear/extractor/matcher.rb +54 -0
  42. data/lib/fear/extractor/matcher/and.rb +36 -0
  43. data/lib/fear/extractor/named_array_splat_matcher.rb +15 -0
  44. data/lib/fear/extractor/pattern.rb +55 -0
  45. data/lib/fear/extractor/typed_identifier_matcher.rb +24 -0
  46. data/lib/fear/extractor/value_matcher.rb +17 -0
  47. data/lib/fear/extractor_api.rb +33 -0
  48. data/lib/fear/failure.rb +32 -10
  49. data/lib/fear/for.rb +14 -69
  50. data/lib/fear/for_api.rb +66 -0
  51. data/lib/fear/future.rb +414 -0
  52. data/lib/fear/future_api.rb +19 -0
  53. data/lib/fear/left.rb +8 -0
  54. data/lib/fear/none.rb +17 -8
  55. data/lib/fear/option.rb +55 -49
  56. data/lib/fear/option_api.rb +38 -0
  57. data/lib/fear/partial_function.rb +9 -12
  58. data/lib/fear/partial_function/empty.rb +1 -1
  59. data/lib/fear/partial_function/guard.rb +8 -20
  60. data/lib/fear/partial_function/lifted.rb +1 -0
  61. data/lib/fear/partial_function_class.rb +10 -0
  62. data/lib/fear/pattern_match.rb +10 -0
  63. data/lib/fear/pattern_matching_api.rb +35 -11
  64. data/lib/fear/promise.rb +87 -0
  65. data/lib/fear/right.rb +8 -0
  66. data/lib/fear/some.rb +22 -3
  67. data/lib/fear/success.rb +22 -1
  68. data/lib/fear/try.rb +82 -67
  69. data/lib/fear/try_api.rb +31 -0
  70. data/lib/fear/unit.rb +28 -0
  71. data/lib/fear/version.rb +1 -1
  72. data/spec/fear/done_spec.rb +3 -3
  73. data/spec/fear/either/mixin_spec.rb +15 -0
  74. data/spec/fear/either_pattern_match_spec.rb +10 -12
  75. data/spec/fear/extractor/array_matcher_spec.rb +228 -0
  76. data/spec/fear/extractor/extractor_matcher_spec.rb +151 -0
  77. data/spec/fear/extractor/grammar_array_spec.rb +23 -0
  78. data/spec/fear/extractor/identified_matcher_spec.rb +47 -0
  79. data/spec/fear/extractor/identifier_matcher_spec.rb +66 -0
  80. data/spec/fear/extractor/pattern_spec.rb +32 -0
  81. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +62 -0
  82. data/spec/fear/extractor/value_matcher_number_spec.rb +77 -0
  83. data/spec/fear/extractor/value_matcher_string_spec.rb +86 -0
  84. data/spec/fear/extractor/value_matcher_symbol_spec.rb +69 -0
  85. data/spec/fear/extractor_api_spec.rb +113 -0
  86. data/spec/fear/extractor_spec.rb +59 -0
  87. data/spec/fear/failure_spec.rb +73 -13
  88. data/spec/fear/for_spec.rb +35 -35
  89. data/spec/fear/future_spec.rb +466 -0
  90. data/spec/fear/guard_spec.rb +4 -4
  91. data/spec/fear/left_spec.rb +40 -14
  92. data/spec/fear/none_spec.rb +28 -12
  93. data/spec/fear/option/mixin_spec.rb +37 -0
  94. data/spec/fear/option_pattern_match_spec.rb +7 -9
  95. data/spec/fear/partial_function_spec.rb +25 -3
  96. data/spec/fear/pattern_match_spec.rb +33 -1
  97. data/spec/fear/promise_spec.rb +94 -0
  98. data/spec/fear/right_spec.rb +37 -9
  99. data/spec/fear/some_spec.rb +32 -6
  100. data/spec/fear/success_spec.rb +32 -4
  101. data/spec/fear/try/mixin_spec.rb +17 -0
  102. data/spec/fear/try_pattern_match_spec.rb +8 -10
  103. data/spec/spec_helper.rb +1 -1
  104. metadata +115 -20
  105. data/Appraisals +0 -32
  106. data/gemfiles/dry_equalizer_0.1.0.gemfile +0 -8
  107. data/gemfiles/dry_equalizer_0.1.0.gemfile.lock +0 -82
  108. data/gemfiles/dry_equalizer_0.2.1.gemfile +0 -8
  109. data/lib/fear/done.rb +0 -22
  110. data/spec/fear/option_spec.rb +0 -15
data/Rakefile CHANGED
@@ -3,195 +3,186 @@ require 'benchmark/ips'
3
3
  require_relative 'lib/fear'
4
4
 
5
5
  namespace :perf do
6
- namespace :guard do
7
- task :and1 do
8
- condition = Integer
6
+ # Contains benchmarking against Dry-rb
7
+ namespace :dry do
8
+ task :some_fmap_vs_fear_some_map do
9
+ require 'dry/monads/maybe'
10
+
11
+ dry = Dry::Monads::Some.new(42)
12
+ fear = Fear.some(42)
9
13
 
10
14
  Benchmark.ips do |x|
11
- x.report('Guard.new') do |n|
12
- Fear::PartialFunction::Guard.new(condition) === n
13
- end
15
+ x.report('Dry') { dry.fmap(&:itself) }
14
16
 
15
- x.report('Guard.single') do |n|
16
- Fear::PartialFunction::Guard.and1(condition) === n
17
- end
17
+ x.report('Fear') { fear.map(&:itself) }
18
18
 
19
19
  x.compare!
20
20
  end
21
21
  end
22
22
 
23
- task :and1 do
24
- first = Integer
23
+ task :do_vs_fear_for do
24
+ require 'dry/monads/maybe'
25
+ require 'dry/monads/do'
25
26
 
26
- and1 = Fear::PartialFunction::Guard.and1(first)
27
- guard = Fear::PartialFunction::Guard.new(first)
27
+ class Operation
28
+ include Dry::Monads::Maybe::Mixin
29
+ include Dry::Monads::Do.for(:call)
28
30
 
29
- Benchmark.ips do |x|
30
- x.report('guard') do |n|
31
- and1 === n
32
- end
31
+ def call
32
+ m1 = Some(1)
33
+ m2 = Some(2)
33
34
 
34
- x.report('single') do |n|
35
- guard === n
36
- end
35
+ one = yield m1
36
+ two = yield m2
37
37
 
38
- x.compare!
38
+ Some(one + two)
39
+ end
39
40
  end
40
- end
41
41
 
42
- task :and2 do
43
- first = Integer
44
- second = ->(x) { x > 2 }
45
-
46
- and2 = Fear::PartialFunction::Guard.and2(first, second)
47
- and_and = Fear::PartialFunction::Guard.new(first).and(Fear::PartialFunction::Guard.new(second))
42
+ op = Operation.new
48
43
 
49
44
  Benchmark.ips do |x|
50
- x.report('and2') do |n|
51
- and2 === n
52
- end
45
+ x.report('Dry') { op.call }
53
46
 
54
- x.report('Guard#and') do |n|
55
- and_and === n
47
+ x.report('Fear') do |_n|
48
+ Fear.for(Fear.some(1), Fear.some(2)) do |one, two|
49
+ one + two
50
+ end
56
51
  end
57
52
 
58
53
  x.compare!
59
54
  end
60
55
  end
56
+ end
61
57
 
62
- task :and3 do
63
- first = Integer
64
- second = ->(x) { x > 2 }
65
- third = ->(x) { x < 10 }
66
-
67
- and3 = Fear::PartialFunction::Guard.and3(first, second, third)
58
+ # Contains internal benchmarking to if optimization works
59
+ namespace :fear do
60
+ task :fear_pattern_extracting_with_vs_without_cache do
61
+ some = Fear.some([:err, 'not found'])
68
62
 
69
- and_and_and = Fear::PartialFunction::Guard.new(first)
70
- .and(Fear::PartialFunction::Guard.new(second))
71
- .and(Fear::PartialFunction::Guard.new(third))
63
+ class WOCache < Fear::Extractor::Pattern
64
+ def initialize(pattern)
65
+ @matcher = compile_pattern_without_cache(pattern)
66
+ end
67
+ end
68
+ pattern = 'Fear::Some([:err, code])'
72
69
 
73
70
  Benchmark.ips do |x|
74
- x.report('Guard.and3') do |n|
75
- and3 === n
71
+ x.report('With cache') do |_n|
72
+ Fear::Extractor::Pattern.new(pattern).extracted_arguments(some)
76
73
  end
77
74
 
78
- x.report('Guard#and') do |n|
79
- and_and_and === n
75
+ x.report('Without cache') do |_n|
76
+ WOCache.new(pattern).extracted_arguments(some)
80
77
  end
81
78
 
82
79
  x.compare!
83
80
  end
84
81
  end
85
- end
86
82
 
87
- require 'qo'
88
- require 'dry/matcher'
83
+ namespace :guard do
84
+ task :and1_vs_new do
85
+ condition = Integer
89
86
 
90
- namespace :pattern_matching do
91
- task :try do
92
- module ExhaustivePatternMatch
93
- def initialize(*)
94
- super
95
- @default ||= self.else { raise Fear::MatchError }
87
+ Benchmark.ips do |x|
88
+ x.report('Guard.new') do |n|
89
+ Fear::PartialFunction::Guard.new(condition) === n
90
+ end
91
+
92
+ x.report('Guard.and1') do |n|
93
+ Fear::PartialFunction::Guard.and1(condition) === n
94
+ end
95
+
96
+ x.compare!
96
97
  end
97
98
  end
98
99
 
99
- SuccessBranch = Qo.create_branch(name: 'success', precondition: Fear::Success, extractor: :get)
100
- FailureBranch = Qo.create_branch(name: 'failure', precondition: Fear::Failure, extractor: :exception)
100
+ task :and2_vs_and do
101
+ first = Integer
102
+ second = ->(x) { x > 2 }
101
103
 
102
- PatternMatch = Qo.create_pattern_match(
103
- branches: [
104
- SuccessBranch,
105
- FailureBranch,
106
- ],
107
- ).prepend(ExhaustivePatternMatch)
104
+ and2 = Fear::PartialFunction::Guard.and2(first, second)
105
+ and_and = Fear::PartialFunction::Guard.new(first).and(Fear::PartialFunction::Guard.new(second))
108
106
 
109
- Fear::Success.include(PatternMatch.mixin(as: :qo_match))
107
+ Benchmark.ips do |x|
108
+ x.report('and2') do |n|
109
+ and2 === n
110
+ end
110
111
 
111
- success_case = Dry::Matcher::Case.new(
112
- match: lambda { |try, *pattern|
113
- try.is_a?(Fear::Success) && pattern.all? { |p| p === try.get }
114
- },
115
- resolve: ->(try) { try.get },
116
- )
112
+ x.report('Guard#and') do |n|
113
+ and_and === n
114
+ end
117
115
 
118
- failure_case = Dry::Matcher::Case.new(
119
- match: lambda { |try, *pattern|
120
- try.is_a?(Fear::Failure) && pattern.all? { |p| p === try.exception }
121
- },
122
- resolve: ->(value) { value.exception },
123
- )
116
+ x.compare!
117
+ end
118
+ end
124
119
 
125
- # Build the matcher
126
- matcher = Dry::Matcher.new(success: success_case, failure: failure_case)
120
+ task :and3_vs_and_and do
121
+ first = Integer
122
+ second = ->(x) { x > 2 }
123
+ third = ->(x) { x < 10 }
127
124
 
128
- success = Fear::Success.new(4)
125
+ and3 = Fear::PartialFunction::Guard.and3(first, second, third)
129
126
 
130
- Benchmark.ips do |x|
131
- x.report('Qo') do
132
- success.qo_match do |m|
133
- m.failure { |y| y }
134
- m.success(->(y) { y % 4 == 0 }) { |y| y }
135
- m.success { 'else' }
136
- end
137
- end
127
+ and_and_and = Fear::PartialFunction::Guard.new(first)
128
+ .and(Fear::PartialFunction::Guard.new(second))
129
+ .and(Fear::PartialFunction::Guard.new(third))
138
130
 
139
- x.report('Fear') do
140
- success.match do |m|
141
- m.failure { |y| y }
142
- m.success(->(y) { y % 4 == 0 }) { |y| y }
143
- m.success { 'else' }
131
+ Benchmark.ips do |x|
132
+ x.report('Guard.and3') do |n|
133
+ and3 === n
144
134
  end
145
- end
146
135
 
147
- x.report('Dr::Matcher') do
148
- matcher.call(success) do |m|
149
- m.failure { |_y| 'failure' }
150
- m.success(->(y) { y % 4 == 0 }) { |y| "2: #{y}" }
151
- m.success { 'else' }
136
+ x.report('Guard#and') do |n|
137
+ and_and_and === n
152
138
  end
153
- end
154
139
 
155
- x.compare!
140
+ x.compare!
141
+ end
156
142
  end
157
143
  end
158
144
 
159
- task :either do
160
- module ExhaustivePatternMatch
161
- def initialize(*)
162
- super
163
- @default ||= self.else { raise Fear::MatchError }
164
- end
145
+ task :pattern_matching_construction_vs_execution do
146
+ matcher = Fear::PatternMatch.new do |m|
147
+ m.case(Integer) { |x| x * 2 }
148
+ m.case(String) { |x| x.to_i(10) * 2 }
165
149
  end
166
150
 
167
- RightBranch = Qo.create_branch(name: 'right', precondition: Fear::Right, extractor: :right_value)
168
- LeftBranch = Qo.create_branch(name: 'left', precondition: Fear::Left, extractor: :left_value)
151
+ Benchmark.ips do |x|
152
+ x.report('construction') do
153
+ Fear::PatternMatch.new do |m|
154
+ m.case(Integer) { |y| y * 2 }
155
+ m.case(String) { |y| y.to_i(10) * 2 }
156
+ end
157
+ end
158
+
159
+ x.report('execution') do
160
+ matcher.call(42)
161
+ end
169
162
 
170
- PatternMatch = Qo.create_pattern_match(
171
- branches: [
172
- RightBranch,
173
- LeftBranch,
174
- ],
175
- ).prepend(ExhaustivePatternMatch)
163
+ x.compare!
164
+ end
165
+ end
166
+ end
176
167
 
177
- Fear::Right.include(PatternMatch.mixin(as: :qo_match))
168
+ namespace :pattern_matching do
169
+ require 'qo'
170
+ require 'dry/matcher'
178
171
 
179
- right = Fear::Right.new(4)
172
+ task :qo_vs_fear_pattern_extraction do
173
+ User = Struct.new(:id, :name)
174
+ user = User.new(42, 'Jane')
180
175
 
181
176
  Benchmark.ips do |x|
182
177
  x.report('Qo') do
183
- right.qo_match do |m|
184
- m.left(->(y) { y % 3 == 0 }) { |y| y }
185
- m.right(->(y) { y % 4 == 0 }) { |y| y }
186
- m.else { 'else' }
178
+ Qo.case(user, destructure: true) do |m|
179
+ m.when(User) { |id, name| [id, name] }
187
180
  end
188
181
  end
189
182
 
190
183
  x.report('Fear') do
191
- right.match do |m|
192
- m.left(->(y) { y % 3 == 0 }) { |y| y }
193
- m.right(->(y) { y % 4 == 0 }) { |y| y }
194
- m.else { 'else' }
184
+ Fear.match(user) do |m|
185
+ m.xcase('User(id, name)') { |id:, name:| [id, name] }
195
186
  end
196
187
  end
197
188
 
@@ -199,7 +190,7 @@ namespace :perf do
199
190
  end
200
191
  end
201
192
 
202
- task :option do
193
+ task :dry_vs_qo_vs_fear_try do
203
194
  module ExhaustivePatternMatch
204
195
  def initialize(*)
205
196
  super
@@ -207,78 +198,57 @@ namespace :perf do
207
198
  end
208
199
  end
209
200
 
210
- SomeBranch = Qo.create_branch(name: 'some', precondition: Fear::Some, extractor: :get)
211
- NoneBranch = Qo.create_branch(name: 'none', precondition: Fear::None)
201
+ SuccessBranch = Qo.create_branch(name: 'success', precondition: Fear::Success, extractor: :get)
202
+ FailureBranch = Qo.create_branch(name: 'failure', precondition: Fear::Failure, extractor: :exception)
212
203
 
213
204
  PatternMatch = Qo.create_pattern_match(
214
- branches: [
215
- SomeBranch,
216
- NoneBranch,
217
- ],
205
+ branches: [SuccessBranch,
206
+ FailureBranch],
218
207
  ).prepend(ExhaustivePatternMatch)
219
208
 
220
- Fear::Some.include(PatternMatch.mixin(as: :qo_match))
221
-
222
- some = Fear::Some.new(4)
209
+ Fear::Success.include(PatternMatch.mixin(as: :qo_match))
223
210
 
224
- some_case = Dry::Matcher::Case.new(
225
- match: lambda { |option, *pattern|
226
- option.is_a?(Fear::Some) && pattern.all? { |p| p === option.get }
211
+ success_case = Dry::Matcher::Case.new(
212
+ match: lambda { |try, *pattern|
213
+ try.is_a?(Fear::Success) && pattern.all? { |p| p === try.get }
227
214
  },
228
215
  resolve: ->(try) { try.get },
229
216
  )
230
217
 
231
- none_case = Dry::Matcher::Case.new(
232
- match: lambda { |option, *pattern|
233
- Fear::None == option && pattern.all? { |p| p === option }
218
+ failure_case = Dry::Matcher::Case.new(
219
+ match: lambda { |try, *pattern|
220
+ try.is_a?(Fear::Failure) && pattern.all? { |p| p === try.exception }
234
221
  },
235
- resolve: ->(value) { value },
236
- )
237
-
238
- else_case = Dry::Matcher::Case.new(
239
- match: ->(*) { true },
240
- resolve: ->(value) { value },
222
+ resolve: ->(value) { value.exception },
241
223
  )
242
224
 
243
225
  # Build the matcher
244
- matcher = Dry::Matcher.new(some: some_case, none: none_case, else: else_case)
226
+ matcher = Dry::Matcher.new(success: success_case, failure: failure_case)
245
227
 
246
- option_matcher = Fear::Option.matcher do |m|
247
- m.some(->(y) { y % 3 == 0 }) { |y| y }
248
- m.some(->(y) { y % 4 == 0 }) { |y| y }
249
- m.none { 'none' }
250
- m.else { 'else' }
251
- end
228
+ success = Fear::Success.new(4)
252
229
 
253
230
  Benchmark.ips do |x|
254
231
  x.report('Qo') do
255
- some.qo_match do |m|
256
- m.some(->(y) { y % 3 == 0 }) { |y| y }
257
- m.some(->(y) { y % 4 == 0 }) { |y| y }
258
- m.none { 'none' }
259
- m.else { 'else' }
232
+ success.qo_match do |m|
233
+ m.failure(&:itself)
234
+ m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
235
+ m.success { 'else' }
260
236
  end
261
237
  end
262
238
 
263
- x.report('Fear::Some#math') do
264
- some.match do |m|
265
- m.some(->(y) { y % 3 == 0 }) { |y| y }
266
- m.some(->(y) { y % 4 == 0 }) { |y| y }
267
- m.none { 'none' }
268
- m.else { 'else' }
239
+ x.report('Fear') do
240
+ success.match do |m|
241
+ m.failure(&:itself)
242
+ m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
243
+ m.success { 'else' }
269
244
  end
270
245
  end
271
246
 
272
- x.report('Fear::Option.mather') do
273
- option_matcher.call(some)
274
- end
275
-
276
- x.report('Dry::Matcher') do
277
- matcher.call(some) do |m|
278
- m.some(->(y) { y % 3 == 0 }) { |y| y }
279
- m.some(->(y) { y % 4 == 0 }) { |y| y }
280
- m.none { 'none' }
281
- m.else { 'else' }
247
+ x.report('Dr::Matcher') do
248
+ matcher.call(success) do |m|
249
+ m.failure(&:itself)
250
+ m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
251
+ m.success { 'else' }
282
252
  end
283
253
  end
284
254
 
@@ -286,7 +256,7 @@ namespace :perf do
286
256
  end
287
257
  end
288
258
 
289
- task :option_execution do
259
+ task :qo_vs_fear_try_execution do
290
260
  module ExhaustivePatternMatch
291
261
  def initialize(*)
292
262
  super
@@ -294,39 +264,36 @@ namespace :perf do
294
264
  end
295
265
  end
296
266
 
297
- SomeBranch = Qo.create_branch(name: 'some', precondition: Fear::Some, extractor: :get)
298
- NoneBranch = Qo.create_branch(name: 'none', precondition: Fear::None)
267
+ SuccessBranch = Qo.create_branch(name: 'success', precondition: Fear::Success, extractor: :get)
268
+ FailureBranch = Qo.create_branch(name: 'failure', precondition: Fear::Failure, extractor: :exception)
299
269
 
300
- PatternMatch = Qo.create_pattern_match(
301
- branches: [
302
- SomeBranch,
303
- NoneBranch,
304
- ],
270
+ QoPatternMatch = Qo.create_pattern_match(
271
+ branches: [SuccessBranch, FailureBranch],
305
272
  ).prepend(ExhaustivePatternMatch)
306
273
 
307
- some = Fear::Some.new(4)
274
+ Fear::Success.include(QoPatternMatch.mixin(as: :qo_match))
308
275
 
309
- qo_matcher = PatternMatch.new do |m|
310
- m.some(->(y) { y % 3 == 0 }) { |y| y }
311
- m.some(->(y) { y % 4 == 0 }) { |y| y }
312
- m.none { 'none' }
313
- m.else { 'else' }
276
+ success = Fear::Success.new(4)
277
+
278
+ qo_matcher = QoPatternMatch.new do |m|
279
+ m.success(1, &:itself)
280
+ m.success(4, &:itself)
281
+ m.failure { 'failure' }
314
282
  end
315
283
 
316
- fear_matcher = Fear::OptionPatternMatch.new do |m|
317
- m.some(->(y) { y % 3 == 0 }) { |y| y }
318
- m.some(->(y) { y % 4 == 0 }) { |y| y }
319
- m.none { 'none' }
320
- m.else { 'else' }
284
+ fear_matcher = Fear::TryPatternMatch.new do |m|
285
+ m.success(1, &:itself)
286
+ m.success(4, &:itself)
287
+ m.failure { 'failure' }
321
288
  end
322
289
 
323
290
  Benchmark.ips do |x|
324
291
  x.report('Qo') do
325
- qo_matcher.call(some)
292
+ qo_matcher.call(success)
326
293
  end
327
294
 
328
295
  x.report('Fear') do
329
- fear_matcher.call(some)
296
+ fear_matcher.call(success)
330
297
  end
331
298
 
332
299
  x.compare!
@@ -343,12 +310,14 @@ namespace :perf do
343
310
  end
344
311
 
345
312
  factorial_pm = Fear.matcher do |m|
346
- m.case(->(n) { n <= 1 }) { 1 }
313
+ m.case(1, &:itself)
314
+ m.case(0, &:itself)
347
315
  m.else { |n| n * factorial_pm.call(n - 1) }
348
316
  end
349
317
 
350
318
  factorial_qo = Qo.match do |m|
351
- m.when(->(n) { n <= 1 }) { 1 }
319
+ m.when(1, &:itself)
320
+ m.when(0, &:itself)
352
321
  m.else { |n| n * factorial_qo.call(n - 1) }
353
322
  end
354
323
 
@@ -368,27 +337,5 @@ namespace :perf do
368
337
  x.compare!
369
338
  end
370
339
  end
371
-
372
- task :construction_vs_execution do
373
- matcher = Fear::PatternMatch.new do |m|
374
- m.case(Integer) { |x| x * 2 }
375
- m.case(String) { |x| x.to_i(10) * 2 }
376
- end
377
-
378
- Benchmark.ips do |x|
379
- x.report('construction') do
380
- Fear::PatternMatch.new do |m|
381
- m.case(Integer) { |y| y * 2 }
382
- m.case(String) { |y| y.to_i(10) * 2 }
383
- end
384
- end
385
-
386
- x.report('execution') do
387
- matcher.call(42)
388
- end
389
-
390
- x.compare!
391
- end
392
- end
393
340
  end
394
341
  end