fear 0.11.0 → 1.0.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.
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