fear 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -60
- data/.travis.yml +8 -4
- data/CHANGELOG.md +7 -1
- data/Gemfile +5 -3
- data/Gemfile.lock +18 -20
- data/README.md +28 -14
- data/Rakefile +61 -60
- data/examples/pattern_extracting.rb +8 -6
- data/examples/pattern_matching_binary_tree_set.rb +4 -2
- data/examples/pattern_matching_number_in_words.rb +46 -42
- data/fear.gemspec +29 -27
- data/lib/fear.rb +44 -37
- data/lib/fear/await.rb +33 -0
- data/lib/fear/awaitable.rb +28 -0
- data/lib/fear/either.rb +2 -0
- data/lib/fear/either_api.rb +2 -0
- data/lib/fear/either_pattern_match.rb +2 -0
- data/lib/fear/empty_partial_function.rb +3 -1
- data/lib/fear/extractor.rb +30 -28
- data/lib/fear/extractor/anonymous_array_splat_matcher.rb +2 -0
- data/lib/fear/extractor/any_matcher.rb +2 -0
- data/lib/fear/extractor/array_head_matcher.rb +2 -0
- data/lib/fear/extractor/array_matcher.rb +2 -0
- data/lib/fear/extractor/array_splat_matcher.rb +2 -0
- data/lib/fear/extractor/empty_list_matcher.rb +2 -0
- data/lib/fear/extractor/extractor_matcher.rb +5 -3
- data/lib/fear/extractor/grammar.rb +5 -3
- data/lib/fear/extractor/identifier_matcher.rb +2 -0
- data/lib/fear/extractor/matcher.rb +5 -3
- data/lib/fear/extractor/matcher/and.rb +3 -1
- data/lib/fear/extractor/named_array_splat_matcher.rb +2 -0
- data/lib/fear/extractor/pattern.rb +7 -5
- data/lib/fear/extractor/typed_identifier_matcher.rb +2 -0
- data/lib/fear/extractor/value_matcher.rb +2 -0
- data/lib/fear/extractor_api.rb +2 -0
- data/lib/fear/failure.rb +2 -0
- data/lib/fear/failure_pattern_match.rb +2 -0
- data/lib/fear/for.rb +4 -2
- data/lib/fear/for_api.rb +3 -1
- data/lib/fear/future.rb +141 -64
- data/lib/fear/future_api.rb +2 -0
- data/lib/fear/left.rb +3 -1
- data/lib/fear/left_pattern_match.rb +2 -0
- data/lib/fear/none.rb +4 -2
- data/lib/fear/none_pattern_match.rb +2 -0
- data/lib/fear/option.rb +3 -1
- data/lib/fear/option_api.rb +2 -0
- data/lib/fear/option_pattern_match.rb +2 -0
- data/lib/fear/partial_function.rb +10 -8
- data/lib/fear/partial_function/and_then.rb +4 -2
- data/lib/fear/partial_function/any.rb +2 -0
- data/lib/fear/partial_function/combined.rb +3 -1
- data/lib/fear/partial_function/empty.rb +2 -0
- data/lib/fear/partial_function/guard.rb +7 -5
- data/lib/fear/partial_function/guard/and.rb +2 -0
- data/lib/fear/partial_function/guard/and3.rb +2 -0
- data/lib/fear/partial_function/guard/or.rb +2 -0
- data/lib/fear/partial_function/lifted.rb +2 -0
- data/lib/fear/partial_function/or_else.rb +3 -1
- data/lib/fear/partial_function_class.rb +3 -1
- data/lib/fear/pattern_match.rb +3 -1
- data/lib/fear/pattern_matching_api.rb +3 -1
- data/lib/fear/promise.rb +11 -3
- data/lib/fear/right.rb +3 -1
- data/lib/fear/right_biased.rb +4 -2
- data/lib/fear/right_pattern_match.rb +2 -0
- data/lib/fear/some.rb +2 -0
- data/lib/fear/some_pattern_match.rb +2 -0
- data/lib/fear/struct.rb +235 -0
- data/lib/fear/success.rb +2 -0
- data/lib/fear/success_pattern_match.rb +2 -0
- data/lib/fear/try.rb +2 -0
- data/lib/fear/try_api.rb +2 -0
- data/lib/fear/try_pattern_match.rb +2 -0
- data/lib/fear/unit.rb +6 -2
- data/lib/fear/utils.rb +4 -2
- data/lib/fear/version.rb +4 -1
- data/spec/fear/done_spec.rb +7 -5
- data/spec/fear/either/mixin_spec.rb +4 -2
- data/spec/fear/either_pattern_match_spec.rb +10 -8
- data/spec/fear/extractor/array_matcher_spec.rb +65 -63
- data/spec/fear/extractor/extractor_matcher_spec.rb +64 -62
- data/spec/fear/extractor/grammar_array_spec.rb +5 -3
- data/spec/fear/extractor/identified_matcher_spec.rb +18 -16
- data/spec/fear/extractor/identifier_matcher_spec.rb +26 -24
- data/spec/fear/extractor/pattern_spec.rb +17 -15
- data/spec/fear/extractor/typed_identifier_matcher_spec.rb +23 -21
- data/spec/fear/extractor/value_matcher_number_spec.rb +29 -27
- data/spec/fear/extractor/value_matcher_string_spec.rb +27 -25
- data/spec/fear/extractor/value_matcher_symbol_spec.rb +24 -22
- data/spec/fear/extractor_api_spec.rb +70 -68
- data/spec/fear/extractor_spec.rb +23 -21
- data/spec/fear/failure_spec.rb +59 -57
- data/spec/fear/for_spec.rb +19 -17
- data/spec/fear/future_spec.rb +456 -240
- data/spec/fear/guard_spec.rb +26 -24
- data/spec/fear/left_spec.rb +60 -58
- data/spec/fear/none_spec.rb +36 -34
- data/spec/fear/option/mixin_spec.rb +9 -7
- data/spec/fear/option_pattern_match_spec.rb +10 -8
- data/spec/fear/partial_function/empty_spec.rb +12 -10
- data/spec/fear/partial_function_and_then_spec.rb +39 -37
- data/spec/fear/partial_function_composition_spec.rb +46 -44
- data/spec/fear/partial_function_or_else_spec.rb +92 -90
- data/spec/fear/partial_function_spec.rb +46 -44
- data/spec/fear/pattern_match_spec.rb +31 -29
- data/spec/fear/promise_spec.rb +19 -17
- data/spec/fear/right_biased/left.rb +28 -26
- data/spec/fear/right_biased/right.rb +51 -49
- data/spec/fear/right_spec.rb +58 -56
- data/spec/fear/some_spec.rb +30 -28
- data/spec/fear/success_spec.rb +50 -48
- data/spec/fear/try/mixin_spec.rb +5 -3
- data/spec/fear/try_pattern_match_spec.rb +10 -8
- data/spec/fear/utils_spec.rb +16 -14
- data/spec/spec_helper.rb +7 -5
- data/spec/struct_spec.rb +226 -0
- metadata +18 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67c81eee97a98c49a029602c26e6835f8bcf2875971619f173899a8986275ae
|
4
|
+
data.tar.gz: 345d18874fdfc360f72816757d5cb74acaa4291ee931c38fb19f82ea9cac3e6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ae2c56f15d445dc73a56c11e1d035daacabdc4df85e4752fcf8500ce2ae7d3e9dd0aef9ae92a7f1e1a0560ead65e8ac774c4ffe7c6c251fa809fdf9b70cfda3
|
7
|
+
data.tar.gz: a0458d44ba7e29725f41285a9687f553b7c2227d99399c28e13502505a5b98844ab5ce31f423f20fdd2b1b015c42b56ea2f4b8bc1f3e01672a851f50ffe87b1f
|
data/.rubocop.yml
CHANGED
@@ -1,63 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
- Exclude
|
1
|
+
inherit_gem:
|
2
|
+
ruby_coding_standard: .rubocop.yml
|
4
3
|
|
5
4
|
AllCops:
|
5
|
+
TargetRubyVersion: 2.4
|
6
6
|
Exclude:
|
7
|
-
|
8
|
-
- 'vendor/bundle/'
|
9
|
-
|
10
|
-
Layout/MultilineMethodCallIndentation:
|
11
|
-
EnforcedStyle: indented
|
12
|
-
|
13
|
-
Metrics/ClassLength:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
Naming/MethodName:
|
17
|
-
Enabled: false
|
18
|
-
|
19
|
-
Naming/UncommunicativeMethodParamName:
|
20
|
-
Enabled: false
|
21
|
-
|
22
|
-
Style/Documentation:
|
23
|
-
Enabled: false
|
24
|
-
|
25
|
-
Style/CaseEquality:
|
26
|
-
Enabled: false
|
27
|
-
|
28
|
-
Style/AccessModifierDeclarations:
|
29
|
-
EnforcedStyle: inline
|
30
|
-
|
31
|
-
Style/GuardClause:
|
32
|
-
Enabled: false
|
33
|
-
|
34
|
-
Style/IfUnlessModifier:
|
35
|
-
Enabled: false
|
36
|
-
|
37
|
-
Style/TrailingCommaInArguments:
|
38
|
-
EnforcedStyleForMultiline: comma
|
39
|
-
|
40
|
-
Style/TrailingCommaInArrayLiteral:
|
41
|
-
EnforcedStyleForMultiline: comma
|
42
|
-
|
43
|
-
Style/TrailingCommaInHashLiteral:
|
44
|
-
EnforcedStyleForMultiline: comma
|
45
|
-
|
46
|
-
Style/NumericPredicate:
|
47
|
-
Enabled: false
|
48
|
-
|
49
|
-
Style/CommentedKeyword:
|
50
|
-
Enabled: false
|
51
|
-
|
52
|
-
Layout/IndentHeredoc:
|
53
|
-
Enabled: false
|
54
|
-
|
55
|
-
Metrics/BlockLength:
|
56
|
-
Exclude:
|
57
|
-
- spec/**/*
|
58
|
-
- Rakefile
|
59
|
-
- fear.gemspec
|
60
|
-
- examples/**/*
|
61
|
-
|
62
|
-
Metrics/LineLength:
|
63
|
-
Max: 120
|
7
|
+
- vendor/**/*
|
data/.travis.yml
CHANGED
@@ -3,10 +3,14 @@ cache:
|
|
3
3
|
bundler: true
|
4
4
|
language: ruby
|
5
5
|
rvm:
|
6
|
-
- 2.4.
|
7
|
-
- 2.5.
|
8
|
-
- 2.6.
|
9
|
-
|
6
|
+
- 2.4.6
|
7
|
+
- 2.5.5
|
8
|
+
- 2.6.3
|
9
|
+
before_install:
|
10
|
+
- rvm use @global
|
11
|
+
- gem uninstall bundler -x || true
|
12
|
+
- gem install bundler --force --version=2.0.1
|
13
|
+
- bundler --version
|
10
14
|
- bundle install
|
11
15
|
script:
|
12
16
|
- bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
## 0
|
1
|
+
## 1.1.0
|
2
|
+
|
3
|
+
* Add `Fear::Await.ready` and `Fear::Await.result`.
|
4
|
+
* Add callback versions with pattern matching `Fear::Future#on_success_match`, `#on_failure_match` and `#on_complete_match`.
|
5
|
+
* Implement immutable `Fear::Struct`
|
6
|
+
|
7
|
+
## 1.0.0
|
2
8
|
|
3
9
|
* Rename `Fear::Done` to `Fear::Unit` ([@bolshakov][])
|
4
10
|
* Don't treat symbols as procs while pattern matching. See [#46](https://github.com/bolshakov/fear/pull/46) for motivation ([@bolshakov][])
|
data/Gemfile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
2
4
|
|
3
5
|
# Specify your gem's dependencies in functional.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
8
|
# gem 'codeclimate-test-reporter', group: :test, require: nil
|
7
9
|
|
8
|
-
gem
|
9
|
-
gem
|
10
|
+
gem "irb"
|
11
|
+
gem "qo", github: "baweaver/qo"
|
data/Gemfile.lock
CHANGED
@@ -8,7 +8,7 @@ GIT
|
|
8
8
|
PATH
|
9
9
|
remote: .
|
10
10
|
specs:
|
11
|
-
fear (1.
|
11
|
+
fear (1.1.0)
|
12
12
|
lru_redux
|
13
13
|
treetop
|
14
14
|
|
@@ -29,16 +29,14 @@ GEM
|
|
29
29
|
dry-core (~> 0.4, >= 0.4.4)
|
30
30
|
dry-equalizer
|
31
31
|
irb (1.0.0)
|
32
|
-
jaro_winkler (1.5.
|
32
|
+
jaro_winkler (1.5.3)
|
33
33
|
lru_redux (1.1.0)
|
34
|
-
parallel (1.
|
35
|
-
parser (2.6.
|
34
|
+
parallel (1.17.0)
|
35
|
+
parser (2.6.3.0)
|
36
36
|
ast (~> 2.4.0)
|
37
37
|
polyglot (0.3.5)
|
38
|
-
powerpack (0.1.2)
|
39
|
-
psych (3.1.0)
|
40
38
|
rainbow (3.0.0)
|
41
|
-
rake (
|
39
|
+
rake (12.3.2)
|
42
40
|
rspec (3.8.0)
|
43
41
|
rspec-core (~> 3.8.0)
|
44
42
|
rspec-expectations (~> 3.8.0)
|
@@ -52,22 +50,22 @@ GEM
|
|
52
50
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
51
|
rspec-support (~> 3.8.0)
|
54
52
|
rspec-support (3.8.0)
|
55
|
-
rubocop (0.
|
53
|
+
rubocop (0.72.0)
|
56
54
|
jaro_winkler (~> 1.5.1)
|
57
55
|
parallel (~> 1.10)
|
58
|
-
parser (>= 2.
|
59
|
-
powerpack (~> 0.1)
|
60
|
-
psych (>= 3.1.0)
|
56
|
+
parser (>= 2.6)
|
61
57
|
rainbow (>= 2.2.2, < 4.0)
|
62
58
|
ruby-progressbar (~> 1.7)
|
63
|
-
unicode-display_width (
|
64
|
-
rubocop-rspec (1.
|
59
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
60
|
+
rubocop-rspec (1.33.0)
|
65
61
|
rubocop (>= 0.60.0)
|
66
|
-
ruby-progressbar (1.10.
|
62
|
+
ruby-progressbar (1.10.1)
|
63
|
+
ruby_coding_standard (0.1.0)
|
64
|
+
rubocop
|
67
65
|
treetop (1.6.10)
|
68
66
|
polyglot (~> 0.3)
|
69
|
-
unicode-display_width (1.
|
70
|
-
yard (0.9.
|
67
|
+
unicode-display_width (1.6.0)
|
68
|
+
yard (0.9.20)
|
71
69
|
|
72
70
|
PLATFORMS
|
73
71
|
ruby
|
@@ -81,11 +79,11 @@ DEPENDENCIES
|
|
81
79
|
fear!
|
82
80
|
irb
|
83
81
|
qo!
|
84
|
-
rake (~>
|
82
|
+
rake (~> 12.3)
|
85
83
|
rspec (~> 3.1)
|
86
|
-
rubocop (=
|
87
|
-
|
84
|
+
rubocop-rspec (= 1.33.0)
|
85
|
+
ruby_coding_standard
|
88
86
|
yard
|
89
87
|
|
90
88
|
BUNDLED WITH
|
91
|
-
|
89
|
+
2.0.1
|
data/README.md
CHANGED
@@ -101,7 +101,7 @@ Fear.none.or_else { Fear.some(21) } #=> Fear.some(21)
|
|
101
101
|
Fear.none.or_else { None } #=> None
|
102
102
|
```
|
103
103
|
|
104
|
-
#### Option#
|
104
|
+
#### Option#include?
|
105
105
|
|
106
106
|
Checks if `Option` has an element that is equal (as determined by `==`) to given values.
|
107
107
|
|
@@ -143,9 +143,9 @@ Fear.none.flat_map { |v| Fear.some(v/2) } #=> None
|
|
143
143
|
Returns `false` if `None` or returns the result of the application of the given predicate to the `Some` value.
|
144
144
|
|
145
145
|
```ruby
|
146
|
-
Fear.some(12).any?
|
147
|
-
Fear.some(7).any?
|
148
|
-
Fear.none.any?
|
146
|
+
Fear.some(12).any? { |v| v > 10 } #=> true
|
147
|
+
Fear.some(7).any? { |v| v > 10 } #=> false
|
148
|
+
Fear.none.any? { |v| v > 10 } #=> false
|
149
149
|
```
|
150
150
|
|
151
151
|
#### Option#select
|
@@ -300,9 +300,9 @@ Fear.failure(ArgumentError.new).to_option #=> None
|
|
300
300
|
Returns `false` if `Failure` or returns the result of the application of the given predicate to the `Success` value.
|
301
301
|
|
302
302
|
```ruby
|
303
|
-
Fear.success(12).any?
|
304
|
-
Fear.success(7).any?
|
305
|
-
Fear.failure(ArgumentError.new).any?
|
303
|
+
Fear.success(12).any? { |v| v > 10 } #=> true
|
304
|
+
Fear.success(7).any? { |v| v > 10 } #=> false
|
305
|
+
Fear.failure(ArgumentError.new).any? { |v| v > 10 } #=> false
|
306
306
|
```
|
307
307
|
|
308
308
|
#### Try#success? and Try#failure?
|
@@ -533,9 +533,9 @@ Fear.left('undefined').to_option #=> Fear::None
|
|
533
533
|
Returns `false` if `Left` or returns the result of the application of the given predicate to the `Right` value.
|
534
534
|
|
535
535
|
```ruby
|
536
|
-
Fear.right(12).any?
|
537
|
-
Fear.right(7).any?
|
538
|
-
Fear.left('undefined').any?
|
536
|
+
Fear.right(12).any? { |v| v > 10 } #=> true
|
537
|
+
Fear.right(7).any? { |v| v > 10 } #=> false
|
538
|
+
Fear.left('undefined').any? { |v| v > 10 } #=> false
|
539
539
|
```
|
540
540
|
|
541
541
|
#### Either#right?, Either#success?
|
@@ -764,7 +764,7 @@ end #=> returns new future of Fear.success(0)
|
|
764
764
|
|
765
765
|
If the future resolved to success or recovery matcher did not matched, it returns the future `Fear::Failure`.
|
766
766
|
|
767
|
-
The second option is `Future#
|
767
|
+
The second option is `Future#fallback_to` method. It allows to fallback to result of another future in case of failure
|
768
768
|
|
769
769
|
```ruby
|
770
770
|
future = Fear.future { fail 'error' }
|
@@ -784,6 +784,20 @@ end.and_then do |m|
|
|
784
784
|
end
|
785
785
|
```
|
786
786
|
|
787
|
+
#### Testing future values
|
788
|
+
|
789
|
+
Sometimes it may be helpful to await for future completion. You can await either future,
|
790
|
+
or result. Don't forget to pass timeout in seconds:
|
791
|
+
|
792
|
+
|
793
|
+
```ruby
|
794
|
+
future = Fear.future { 42 }
|
795
|
+
|
796
|
+
Fear::Await.result(future, 3) #=> 42
|
797
|
+
|
798
|
+
Fear::Await.ready(future, 3) #=> Fear::Future.successful(42)
|
799
|
+
```
|
800
|
+
|
787
801
|
### For composition ([API Documentation](http://www.rubydoc.info/github/bolshakov/fear/master/Fear/ForApi))
|
788
802
|
|
789
803
|
Provides syntactic sugar for composition of multiple monadic operations.
|
@@ -1095,13 +1109,13 @@ factorial.(10) #=> 3628800
|
|
1095
1109
|
Fibonacci number
|
1096
1110
|
|
1097
1111
|
```ruby
|
1098
|
-
|
1112
|
+
fibonacci = Fear.matcher do |m|
|
1099
1113
|
m.case(0) { 0 }
|
1100
1114
|
m.case(1) { 1 }
|
1101
|
-
m.case(->(n) { n > 1}) { |n|
|
1115
|
+
m.case(->(n) { n > 1}) { |n| fibonacci.(n - 1) + fibonacci.(n - 2) }
|
1102
1116
|
end
|
1103
1117
|
|
1104
|
-
|
1118
|
+
fibonacci.(10) #=> 55
|
1105
1119
|
```
|
1106
1120
|
|
1107
1121
|
Binary tree set implemented using pattern matching https://gist.github.com/bolshakov/3c51bbf7be95066d55d6d1ac8c605a1d
|
data/Rakefile
CHANGED
@@ -1,28 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "benchmark/ips"
|
5
|
+
require_relative "lib/fear"
|
4
6
|
|
5
7
|
namespace :perf do
|
6
8
|
# Contains benchmarking against Dry-rb
|
7
9
|
namespace :dry do
|
8
10
|
task :some_fmap_vs_fear_some_map do
|
9
|
-
require
|
11
|
+
require "dry/monads/maybe"
|
10
12
|
|
11
13
|
dry = Dry::Monads::Some.new(42)
|
12
14
|
fear = Fear.some(42)
|
13
15
|
|
14
16
|
Benchmark.ips do |x|
|
15
|
-
x.report(
|
17
|
+
x.report("Dry") { dry.fmap(&:itself) }
|
16
18
|
|
17
|
-
x.report(
|
19
|
+
x.report("Fear") { fear.map(&:itself) }
|
18
20
|
|
19
21
|
x.compare!
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
task :do_vs_fear_for do
|
24
|
-
require
|
25
|
-
require
|
26
|
+
require "dry/monads/maybe"
|
27
|
+
require "dry/monads/do"
|
26
28
|
|
27
29
|
class Operation
|
28
30
|
include Dry::Monads::Maybe::Mixin
|
@@ -42,9 +44,9 @@ namespace :perf do
|
|
42
44
|
op = Operation.new
|
43
45
|
|
44
46
|
Benchmark.ips do |x|
|
45
|
-
x.report(
|
47
|
+
x.report("Dry") { op.() }
|
46
48
|
|
47
|
-
x.report(
|
49
|
+
x.report("Fear") do |_n|
|
48
50
|
Fear.for(Fear.some(1), Fear.some(2)) do |one, two|
|
49
51
|
one + two
|
50
52
|
end
|
@@ -58,21 +60,21 @@ namespace :perf do
|
|
58
60
|
# Contains internal benchmarking to if optimization works
|
59
61
|
namespace :fear do
|
60
62
|
task :fear_pattern_extracting_with_vs_without_cache do
|
61
|
-
some = Fear.some([:err,
|
63
|
+
some = Fear.some([:err, "not found"])
|
62
64
|
|
63
65
|
class WOCache < Fear::Extractor::Pattern
|
64
66
|
def initialize(pattern)
|
65
67
|
@matcher = compile_pattern_without_cache(pattern)
|
66
68
|
end
|
67
69
|
end
|
68
|
-
pattern =
|
70
|
+
pattern = "Fear::Some([:err, code])"
|
69
71
|
|
70
72
|
Benchmark.ips do |x|
|
71
|
-
x.report(
|
73
|
+
x.report("With cache") do |_n|
|
72
74
|
Fear::Extractor::Pattern.new(pattern).extracted_arguments(some)
|
73
75
|
end
|
74
76
|
|
75
|
-
x.report(
|
77
|
+
x.report("Without cache") do |_n|
|
76
78
|
WOCache.new(pattern).extracted_arguments(some)
|
77
79
|
end
|
78
80
|
|
@@ -85,11 +87,11 @@ namespace :perf do
|
|
85
87
|
condition = Integer
|
86
88
|
|
87
89
|
Benchmark.ips do |x|
|
88
|
-
x.report(
|
90
|
+
x.report("Guard.new") do |n|
|
89
91
|
Fear::PartialFunction::Guard.new(condition) === n
|
90
92
|
end
|
91
93
|
|
92
|
-
x.report(
|
94
|
+
x.report("Guard.and1") do |n|
|
93
95
|
Fear::PartialFunction::Guard.and1(condition) === n
|
94
96
|
end
|
95
97
|
|
@@ -105,11 +107,11 @@ namespace :perf do
|
|
105
107
|
and_and = Fear::PartialFunction::Guard.new(first).and(Fear::PartialFunction::Guard.new(second))
|
106
108
|
|
107
109
|
Benchmark.ips do |x|
|
108
|
-
x.report(
|
110
|
+
x.report("and2") do |n|
|
109
111
|
and2 === n
|
110
112
|
end
|
111
113
|
|
112
|
-
x.report(
|
114
|
+
x.report("Guard#and") do |n|
|
113
115
|
and_and === n
|
114
116
|
end
|
115
117
|
|
@@ -120,7 +122,7 @@ namespace :perf do
|
|
120
122
|
task :and3_vs_and_and do
|
121
123
|
first = Integer
|
122
124
|
second = ->(x) { x > 2 }
|
123
|
-
third = ->(x) {
|
125
|
+
third = ->(x) { x < 10 }
|
124
126
|
|
125
127
|
and3 = Fear::PartialFunction::Guard.and3(first, second, third)
|
126
128
|
|
@@ -129,11 +131,11 @@ namespace :perf do
|
|
129
131
|
.and(Fear::PartialFunction::Guard.new(third))
|
130
132
|
|
131
133
|
Benchmark.ips do |x|
|
132
|
-
x.report(
|
134
|
+
x.report("Guard.and3") do |n|
|
133
135
|
and3 === n
|
134
136
|
end
|
135
137
|
|
136
|
-
x.report(
|
138
|
+
x.report("Guard#and") do |n|
|
137
139
|
and_and_and === n
|
138
140
|
end
|
139
141
|
|
@@ -149,15 +151,15 @@ namespace :perf do
|
|
149
151
|
end
|
150
152
|
|
151
153
|
Benchmark.ips do |x|
|
152
|
-
x.report(
|
154
|
+
x.report("construction") do
|
153
155
|
Fear::PatternMatch.new do |m|
|
154
156
|
m.case(Integer) { |y| y * 2 }
|
155
157
|
m.case(String) { |y| y.to_i(10) * 2 }
|
156
158
|
end
|
157
159
|
end
|
158
160
|
|
159
|
-
x.report(
|
160
|
-
matcher.
|
161
|
+
x.report("execution") do
|
162
|
+
matcher.(42)
|
161
163
|
end
|
162
164
|
|
163
165
|
x.compare!
|
@@ -166,23 +168,23 @@ namespace :perf do
|
|
166
168
|
end
|
167
169
|
|
168
170
|
namespace :pattern_matching do
|
169
|
-
require
|
170
|
-
require
|
171
|
+
require "qo"
|
172
|
+
require "dry/matcher"
|
171
173
|
|
172
174
|
task :qo_vs_fear_pattern_extraction do
|
173
175
|
User = Struct.new(:id, :name)
|
174
|
-
user = User.new(42,
|
176
|
+
user = User.new(42, "Jane")
|
175
177
|
|
176
178
|
Benchmark.ips do |x|
|
177
|
-
x.report(
|
179
|
+
x.report("Qo") do
|
178
180
|
Qo.case(user, destructure: true) do |m|
|
179
181
|
m.when(User) { |id, name| [id, name] }
|
180
182
|
end
|
181
183
|
end
|
182
184
|
|
183
|
-
x.report(
|
185
|
+
x.report("Fear") do
|
184
186
|
Fear.match(user) do |m|
|
185
|
-
m.xcase(
|
187
|
+
m.xcase("User(id, name)") { |id:, name:| [id, name] }
|
186
188
|
end
|
187
189
|
end
|
188
190
|
|
@@ -198,25 +200,24 @@ namespace :perf do
|
|
198
200
|
end
|
199
201
|
end
|
200
202
|
|
201
|
-
SuccessBranch = Qo.create_branch(name:
|
202
|
-
FailureBranch = Qo.create_branch(name:
|
203
|
+
SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
|
204
|
+
FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
|
203
205
|
|
204
206
|
PatternMatch = Qo.create_pattern_match(
|
205
|
-
branches: [SuccessBranch,
|
206
|
-
FailureBranch],
|
207
|
+
branches: [SuccessBranch, FailureBranch],
|
207
208
|
).prepend(ExhaustivePatternMatch)
|
208
209
|
|
209
210
|
Fear::Success.include(PatternMatch.mixin(as: :qo_match))
|
210
211
|
|
211
212
|
success_case = Dry::Matcher::Case.new(
|
212
|
-
match:
|
213
|
+
match: ->(try, *pattern) {
|
213
214
|
try.is_a?(Fear::Success) && pattern.all? { |p| p === try.get }
|
214
215
|
},
|
215
216
|
resolve: ->(try) { try.get },
|
216
217
|
)
|
217
218
|
|
218
219
|
failure_case = Dry::Matcher::Case.new(
|
219
|
-
match:
|
220
|
+
match: ->(try, *pattern) {
|
220
221
|
try.is_a?(Fear::Failure) && pattern.all? { |p| p === try.exception }
|
221
222
|
},
|
222
223
|
resolve: ->(value) { value.exception },
|
@@ -228,27 +229,27 @@ namespace :perf do
|
|
228
229
|
success = Fear::Success.new(4)
|
229
230
|
|
230
231
|
Benchmark.ips do |x|
|
231
|
-
x.report(
|
232
|
+
x.report("Qo") do
|
232
233
|
success.qo_match do |m|
|
233
234
|
m.failure(&:itself)
|
234
235
|
m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
|
235
|
-
m.success {
|
236
|
+
m.success { "else" }
|
236
237
|
end
|
237
238
|
end
|
238
239
|
|
239
|
-
x.report(
|
240
|
+
x.report("Fear") do
|
240
241
|
success.match do |m|
|
241
242
|
m.failure(&:itself)
|
242
243
|
m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
|
243
|
-
m.success {
|
244
|
+
m.success { "else" }
|
244
245
|
end
|
245
246
|
end
|
246
247
|
|
247
|
-
x.report(
|
248
|
-
matcher.
|
248
|
+
x.report("Dr::Matcher") do
|
249
|
+
matcher.(success) do |m|
|
249
250
|
m.failure(&:itself)
|
250
251
|
m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
|
251
|
-
m.success {
|
252
|
+
m.success { "else" }
|
252
253
|
end
|
253
254
|
end
|
254
255
|
|
@@ -264,8 +265,8 @@ namespace :perf do
|
|
264
265
|
end
|
265
266
|
end
|
266
267
|
|
267
|
-
SuccessBranch = Qo.create_branch(name:
|
268
|
-
FailureBranch = Qo.create_branch(name:
|
268
|
+
SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
|
269
|
+
FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
|
269
270
|
|
270
271
|
QoPatternMatch = Qo.create_pattern_match(
|
271
272
|
branches: [SuccessBranch, FailureBranch],
|
@@ -278,22 +279,22 @@ namespace :perf do
|
|
278
279
|
qo_matcher = QoPatternMatch.new do |m|
|
279
280
|
m.success(1, &:itself)
|
280
281
|
m.success(4, &:itself)
|
281
|
-
m.failure {
|
282
|
+
m.failure { "failure" }
|
282
283
|
end
|
283
284
|
|
284
285
|
fear_matcher = Fear::TryPatternMatch.new do |m|
|
285
286
|
m.success(1, &:itself)
|
286
287
|
m.success(4, &:itself)
|
287
|
-
m.failure {
|
288
|
+
m.failure { "failure" }
|
288
289
|
end
|
289
290
|
|
290
291
|
Benchmark.ips do |x|
|
291
|
-
x.report(
|
292
|
-
qo_matcher.
|
292
|
+
x.report("Qo") do
|
293
|
+
qo_matcher.(success)
|
293
294
|
end
|
294
295
|
|
295
|
-
x.report(
|
296
|
-
fear_matcher.
|
296
|
+
x.report("Fear") do
|
297
|
+
fear_matcher.(success)
|
297
298
|
end
|
298
299
|
|
299
300
|
x.compare!
|
@@ -305,33 +306,33 @@ namespace :perf do
|
|
305
306
|
if n <= 1
|
306
307
|
1
|
307
308
|
else
|
308
|
-
n * factorial_proc.
|
309
|
+
n * factorial_proc.(n - 1)
|
309
310
|
end
|
310
311
|
end
|
311
312
|
|
312
313
|
factorial_pm = Fear.matcher do |m|
|
313
314
|
m.case(1, &:itself)
|
314
315
|
m.case(0, &:itself)
|
315
|
-
m.else { |n| n * factorial_pm.
|
316
|
+
m.else { |n| n * factorial_pm.(n - 1) }
|
316
317
|
end
|
317
318
|
|
318
319
|
factorial_qo = Qo.match do |m|
|
319
320
|
m.when(1, &:itself)
|
320
321
|
m.when(0, &:itself)
|
321
|
-
m.else { |n| n * factorial_qo.
|
322
|
+
m.else { |n| n * factorial_qo.(n - 1) }
|
322
323
|
end
|
323
324
|
|
324
325
|
Benchmark.ips do |x|
|
325
|
-
x.report(
|
326
|
-
factorial_proc.
|
326
|
+
x.report("Proc") do
|
327
|
+
factorial_proc.(100)
|
327
328
|
end
|
328
329
|
|
329
|
-
x.report(
|
330
|
-
factorial_pm.
|
330
|
+
x.report("Fear") do
|
331
|
+
factorial_pm.(100)
|
331
332
|
end
|
332
333
|
|
333
|
-
x.report(
|
334
|
-
factorial_qo.
|
334
|
+
x.report("Qo") do
|
335
|
+
factorial_qo.(100)
|
335
336
|
end
|
336
337
|
|
337
338
|
x.compare!
|