fear 2.0.1 → 3.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.
- checksums.yaml +4 -4
- data/.github/workflows/spec.yml +1 -5
- data/CHANGELOG.md +8 -0
- data/Gemfile +14 -2
- data/Gemfile.lock +48 -61
- data/LICENSE.txt +1 -1
- data/README.md +18 -70
- data/Rakefile +32 -119
- 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/fear.gemspec +4 -19
- data/lib/fear/either/left_projection.rb +237 -0
- data/lib/fear/either/pattern_match.rb +49 -0
- data/lib/fear/either.rb +20 -11
- data/lib/fear/either_api.rb +2 -4
- data/lib/fear/empty_partial_function.rb +1 -1
- data/lib/fear/failure/pattern_match.rb +14 -0
- data/lib/fear/failure.rb +1 -1
- data/lib/fear/for_api.rb +0 -2
- data/lib/fear/future.rb +1 -1
- data/lib/fear/future_api.rb +0 -5
- data/lib/fear/left/pattern_match.rb +15 -0
- data/lib/fear/left.rb +1 -1
- 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 +1 -5
- data/lib/fear/option_api.rb +1 -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 +0 -2
- data/lib/fear/partial_function.rb +0 -9
- data/lib/fear/partial_function_class.rb +1 -1
- data/lib/fear/pattern_match.rb +3 -2
- data/lib/fear/pattern_matching_api.rb +0 -3
- data/lib/fear/right/pattern_match.rb +15 -0
- data/lib/fear/right.rb +1 -1
- data/lib/fear/right_biased.rb +2 -0
- data/lib/fear/some/pattern_match.rb +15 -0
- data/lib/fear/some.rb +1 -1
- data/lib/fear/success/pattern_match.rb +16 -0
- data/lib/fear/success.rb +1 -1
- data/lib/fear/try/pattern_match.rb +29 -0
- data/lib/fear/try.rb +3 -7
- data/lib/fear/try_api.rb +0 -2
- 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} +1 -1
- data/spec/fear/{option_pattern_match_spec.rb → option/pattern_match_spec.rb} +1 -1
- data/spec/fear/partial_function/empty_spec.rb +1 -1
- data/spec/fear/{try_pattern_match_spec.rb → try/try_pattern_match_spec.rb} +1 -1
- data/spec/support/.keep +0 -0
- metadata +29 -255
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fa7f6ac3aad235456d308554fccd82ea9c8d7ed5cbb1774047976bed3bd8278
|
4
|
+
data.tar.gz: c2dbd3ad5dd6b1780034598d6ca9ea91f55f5dfaa3bf0ba7852b7ebebb9f7944
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 164aeb41d3d210239adf73743fcdc3dd472fda922f7a23b6f08960700b3b1cc4dac838bce130cf979100e0f80de4616b5f9baeb2234d943d255228c7fd22ec80
|
7
|
+
data.tar.gz: 72b3372bc24b607adfb71b40f65fd2c71b59ba9a2487e7e297ab6bad3452c502ab0b8d39d7ae8b7ada59f2a3bb8d327cc91a75ac8c1c69a139dc4acbf10d78f5
|
data/.github/workflows/spec.yml
CHANGED
@@ -7,7 +7,7 @@ jobs:
|
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
strategy:
|
9
9
|
matrix:
|
10
|
-
ruby: ['
|
10
|
+
ruby: ['3.1', "3.2", "3.3", "truffleruby+graalvm-head"]
|
11
11
|
name: ${{ matrix.ruby }}
|
12
12
|
|
13
13
|
steps:
|
@@ -19,10 +19,6 @@ jobs:
|
|
19
19
|
- name: Install dependencies
|
20
20
|
run: bundle install
|
21
21
|
- name: Test
|
22
|
-
if: ${{ contains(matrix.ruby, 'truffleruby') }}
|
23
|
-
run: bundle exec rspec --exclude-pattern "**/*_pattern_matching_spec.rb"
|
24
|
-
- name: Test
|
25
|
-
if: ${{ !contains(matrix.ruby, 'truffleruby') }}
|
26
22
|
run: bundle exec rspec
|
27
23
|
- name: Coveralls
|
28
24
|
uses: coverallsapp/github-action@v1.1.2
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -5,5 +5,17 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in functional.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "
|
9
|
-
gem "
|
8
|
+
gem "benchmark-ips"
|
9
|
+
gem "concurrent-ruby"
|
10
|
+
gem "dry-matcher"
|
11
|
+
gem "dry-monads"
|
12
|
+
gem "dry-types"
|
13
|
+
gem "fear-rspec"
|
14
|
+
gem "rake", "~> 13.0"
|
15
|
+
gem "rspec", "~> 3.1"
|
16
|
+
gem "rubocop", "1.32.0"
|
17
|
+
gem "rubocop-rspec", "1.34.0"
|
18
|
+
gem "ruby_coding_standard"
|
19
|
+
gem "simplecov"
|
20
|
+
gem "simplecov-lcov"
|
21
|
+
gem "yard"
|
data/Gemfile.lock
CHANGED
@@ -1,76 +1,65 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/baweaver/qo.git
|
3
|
-
revision: 8951ce899559118eb60321014b43cf4211730bd0
|
4
|
-
specs:
|
5
|
-
qo (0.99.0)
|
6
|
-
any (= 0.1.0)
|
7
|
-
|
8
1
|
PATH
|
9
2
|
remote: .
|
10
3
|
specs:
|
11
|
-
fear (
|
4
|
+
fear (3.0.0)
|
5
|
+
zeitwerk
|
12
6
|
|
13
7
|
GEM
|
14
8
|
remote: https://rubygems.org/
|
15
9
|
specs:
|
16
|
-
any (0.1.0)
|
17
10
|
ast (2.4.2)
|
18
|
-
benchmark-ips (2.
|
19
|
-
|
20
|
-
|
11
|
+
benchmark-ips (2.13.0)
|
12
|
+
bigdecimal (3.1.7)
|
13
|
+
concurrent-ruby (1.2.3)
|
14
|
+
diff-lcs (1.5.1)
|
21
15
|
docile (1.4.0)
|
22
|
-
dry-
|
23
|
-
concurrent-ruby (~> 1.0)
|
24
|
-
dry-core (~> 0.5, >= 0.5.0)
|
25
|
-
dry-container (0.7.2)
|
26
|
-
concurrent-ruby (~> 1.0)
|
27
|
-
dry-configurable (~> 0.1, >= 0.1.3)
|
28
|
-
dry-core (0.5.0)
|
16
|
+
dry-core (1.0.1)
|
29
17
|
concurrent-ruby (~> 1.0)
|
30
|
-
|
31
|
-
dry-inflector (0.
|
32
|
-
dry-logic (1.
|
18
|
+
zeitwerk (~> 2.6)
|
19
|
+
dry-inflector (1.0.0)
|
20
|
+
dry-logic (1.5.0)
|
33
21
|
concurrent-ruby (~> 1.0)
|
34
|
-
dry-core (~> 0
|
35
|
-
|
36
|
-
|
37
|
-
|
22
|
+
dry-core (~> 1.0, < 2)
|
23
|
+
zeitwerk (~> 2.6)
|
24
|
+
dry-matcher (1.0.0)
|
25
|
+
dry-core (~> 1.0, < 2)
|
26
|
+
dry-monads (1.6.0)
|
38
27
|
concurrent-ruby (~> 1.0)
|
39
|
-
dry-core (~> 0
|
40
|
-
|
41
|
-
dry-types (1.
|
28
|
+
dry-core (~> 1.0, < 2)
|
29
|
+
zeitwerk (~> 2.6)
|
30
|
+
dry-types (1.7.2)
|
31
|
+
bigdecimal (~> 3.0)
|
42
32
|
concurrent-ruby (~> 1.0)
|
43
|
-
dry-
|
44
|
-
dry-
|
45
|
-
dry-
|
46
|
-
|
33
|
+
dry-core (~> 1.0)
|
34
|
+
dry-inflector (~> 1.0)
|
35
|
+
dry-logic (~> 1.4)
|
36
|
+
zeitwerk (~> 2.6)
|
47
37
|
fear-rspec (0.3.0)
|
48
38
|
fear (>= 1.0.0)
|
49
39
|
rspec (~> 3.0)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
parallel (1.22.1)
|
54
|
-
parser (3.1.2.0)
|
40
|
+
json (2.7.1)
|
41
|
+
parallel (1.24.0)
|
42
|
+
parser (3.3.0.5)
|
55
43
|
ast (~> 2.4.1)
|
44
|
+
racc
|
45
|
+
racc (1.7.3)
|
56
46
|
rainbow (3.1.1)
|
57
47
|
rake (13.1.0)
|
58
|
-
regexp_parser (2.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
rspec-
|
63
|
-
rspec-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
rspec-expectations (3.12.0)
|
48
|
+
regexp_parser (2.9.0)
|
49
|
+
rexml (3.2.6)
|
50
|
+
rspec (3.13.0)
|
51
|
+
rspec-core (~> 3.13.0)
|
52
|
+
rspec-expectations (~> 3.13.0)
|
53
|
+
rspec-mocks (~> 3.13.0)
|
54
|
+
rspec-core (3.13.0)
|
55
|
+
rspec-support (~> 3.13.0)
|
56
|
+
rspec-expectations (3.13.0)
|
68
57
|
diff-lcs (>= 1.2.0, < 2.0)
|
69
|
-
rspec-support (~> 3.
|
70
|
-
rspec-mocks (3.
|
58
|
+
rspec-support (~> 3.13.0)
|
59
|
+
rspec-mocks (3.13.0)
|
71
60
|
diff-lcs (>= 1.2.0, < 2.0)
|
72
|
-
rspec-support (~> 3.
|
73
|
-
rspec-support (3.
|
61
|
+
rspec-support (~> 3.13.0)
|
62
|
+
rspec-support (3.13.1)
|
74
63
|
rubocop (1.32.0)
|
75
64
|
json (~> 2.3)
|
76
65
|
parallel (~> 1.10)
|
@@ -81,11 +70,11 @@ GEM
|
|
81
70
|
rubocop-ast (>= 1.19.1, < 2.0)
|
82
71
|
ruby-progressbar (~> 1.7)
|
83
72
|
unicode-display_width (>= 1.4.0, < 3.0)
|
84
|
-
rubocop-ast (1.
|
85
|
-
parser (>= 3.
|
73
|
+
rubocop-ast (1.31.2)
|
74
|
+
parser (>= 3.3.0.4)
|
86
75
|
rubocop-rspec (1.34.0)
|
87
76
|
rubocop (>= 0.60.0)
|
88
|
-
ruby-progressbar (1.
|
77
|
+
ruby-progressbar (1.13.0)
|
89
78
|
ruby_coding_standard (0.4.0)
|
90
79
|
rubocop (~> 1.32.0)
|
91
80
|
simplecov (0.22.0)
|
@@ -95,23 +84,21 @@ GEM
|
|
95
84
|
simplecov-html (0.12.3)
|
96
85
|
simplecov-lcov (0.8.0)
|
97
86
|
simplecov_json_formatter (0.1.4)
|
98
|
-
unicode-display_width (2.
|
99
|
-
yard (0.9.
|
87
|
+
unicode-display_width (2.5.0)
|
88
|
+
yard (0.9.36)
|
89
|
+
zeitwerk (2.6.13)
|
100
90
|
|
101
91
|
PLATFORMS
|
102
92
|
ruby
|
103
93
|
|
104
94
|
DEPENDENCIES
|
105
95
|
benchmark-ips
|
106
|
-
bundler
|
107
96
|
concurrent-ruby
|
108
97
|
dry-matcher
|
109
98
|
dry-monads
|
110
99
|
dry-types
|
111
100
|
fear!
|
112
101
|
fear-rspec
|
113
|
-
irb
|
114
|
-
qo!
|
115
102
|
rake (~> 13.0)
|
116
103
|
rspec (~> 3.1)
|
117
104
|
rubocop (= 1.32.0)
|
@@ -122,4 +109,4 @@ DEPENDENCIES
|
|
122
109
|
yard
|
123
110
|
|
124
111
|
BUNDLED WITH
|
125
|
-
2.
|
112
|
+
2.5.7
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -632,6 +632,20 @@ Fear.left('left').swap #=> Fear.right('left')
|
|
632
632
|
Fear.right('right').swap #=> Fear.left('left')
|
633
633
|
```
|
634
634
|
|
635
|
+
#### Either#left
|
636
|
+
|
637
|
+
Projects this `Fear::Either` as a `Fear::Left`.
|
638
|
+
This allows performing right-biased operation of the left
|
639
|
+
side of the `Fear::Either`.
|
640
|
+
|
641
|
+
```ruby
|
642
|
+
Fear.left(42).left.map(&:succ) #=> Fear.left(43)
|
643
|
+
Fear.right(42).left.map(&:succ) #=> Fear.left(42)
|
644
|
+
|
645
|
+
Fear.left(42).left.select(&:even?) #=> Fear.left(42)
|
646
|
+
Fear.right(42).left.select(&:odd?) #=> Fear.right(42)
|
647
|
+
```
|
648
|
+
|
635
649
|
#### Either#reduce
|
636
650
|
|
637
651
|
Applies `reduce_left` if this is a `Left` or `reduce_right` if this is a `Right`.
|
@@ -1179,76 +1193,7 @@ end
|
|
1179
1193
|
|
1180
1194
|
### Dry-Types integration
|
1181
1195
|
|
1182
|
-
|
1183
|
-
|
1184
|
-
NOTE: Requires the dry-tyes gem to be loaded.
|
1185
|
-
|
1186
|
-
Load the `:fear_option` extension in your application.
|
1187
|
-
|
1188
|
-
```ruby
|
1189
|
-
require 'dry-types'
|
1190
|
-
require 'dry/types/fear'
|
1191
|
-
|
1192
|
-
Dry::Types.load_extensions(:fear_option)
|
1193
|
-
|
1194
|
-
module Types
|
1195
|
-
include Dry.Types()
|
1196
|
-
end
|
1197
|
-
```
|
1198
|
-
|
1199
|
-
Append .option to a Type to return a `Fear::Option` object:
|
1200
|
-
|
1201
|
-
```ruby
|
1202
|
-
Types::Option::Strict::Integer[nil]
|
1203
|
-
#=> Fear.none
|
1204
|
-
Types::Option::Coercible::String[nil]
|
1205
|
-
#=> Fear.none
|
1206
|
-
Types::Option::Strict::Integer[123]
|
1207
|
-
#=> Fear.some(123)
|
1208
|
-
Types::Option::Strict::String[123]
|
1209
|
-
#=> Fear.some(123)
|
1210
|
-
Types::Option::Coercible::Float['12.3']
|
1211
|
-
#=> Fear.some(12.3)
|
1212
|
-
```
|
1213
|
-
|
1214
|
-
'Option' types can also accessed by calling '.option' on a regular type:
|
1215
|
-
|
1216
|
-
```ruby
|
1217
|
-
Types::Strict::Integer.option # equivalent to Types::Option::Strict::Integer
|
1218
|
-
```
|
1219
|
-
|
1220
|
-
|
1221
|
-
You can define your own optional types:
|
1222
|
-
|
1223
|
-
```ruby
|
1224
|
-
option_string = Types::Strict::String.option
|
1225
|
-
option_string[nil]
|
1226
|
-
# => Fear.none
|
1227
|
-
option_string[nil].map(&:upcase)
|
1228
|
-
# => Fear.none
|
1229
|
-
option_string['something']
|
1230
|
-
# => Fear.some('something')
|
1231
|
-
option_string['something'].map(&:upcase)
|
1232
|
-
# => Fear.some('SOMETHING')
|
1233
|
-
option_string['something'].map(&:upcase).get_or_else { 'NOTHING' }
|
1234
|
-
# => "SOMETHING"
|
1235
|
-
```
|
1236
|
-
|
1237
|
-
You can use it with dry-struct as well:
|
1238
|
-
|
1239
|
-
```ruby
|
1240
|
-
class User < Dry::Struct
|
1241
|
-
attribute :name, Types::Coercible::String
|
1242
|
-
attribute :age, Types::Coercible::Integer.option
|
1243
|
-
end
|
1244
|
-
|
1245
|
-
user = User.new(name: 'Bob', age: nil)
|
1246
|
-
user.name #=> "Bob"
|
1247
|
-
user.age #=> Fear.none
|
1248
|
-
|
1249
|
-
user = User.new(name: 'Bob', age: 42)
|
1250
|
-
user.age #=> Fear.some(42)
|
1251
|
-
```
|
1196
|
+
To use `Fear::Option` as optional type for `Dry::Types` use the [dry-types-fear] gem.
|
1252
1197
|
|
1253
1198
|
## Testing
|
1254
1199
|
|
@@ -1272,3 +1217,6 @@ provides a bunch of rspec matchers.
|
|
1272
1217
|
* [maybe](https://github.com/bhb/maybe)
|
1273
1218
|
* [ruby-possibly](https://github.com/rap1ds/ruby-possibly)
|
1274
1219
|
* [rumonade](https://github.com/ms-ati/rumonade)
|
1220
|
+
|
1221
|
+
|
1222
|
+
[dry-types-fear]: https://github.com/bolshakov/dry-types-fear
|
data/Rakefile
CHANGED
@@ -2,15 +2,16 @@
|
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "benchmark/ips"
|
5
|
+
require "dry/monads"
|
5
6
|
require_relative "lib/fear"
|
6
7
|
|
8
|
+
include Dry::Monads[:maybe]
|
9
|
+
|
7
10
|
namespace :perf do
|
8
11
|
# Contains benchmarking against Dry-rb
|
9
12
|
namespace :dry do
|
10
13
|
task :some_fmap_vs_fear_some_map do
|
11
|
-
|
12
|
-
|
13
|
-
dry = Dry::Monads::Some.new(42)
|
14
|
+
dry = Some(42)
|
14
15
|
fear = Fear.some(42)
|
15
16
|
|
16
17
|
Benchmark.ips do |x|
|
@@ -23,11 +24,9 @@ namespace :perf do
|
|
23
24
|
end
|
24
25
|
|
25
26
|
task :do_vs_fear_for do
|
26
|
-
require "dry/monads/maybe"
|
27
27
|
require "dry/monads/do"
|
28
28
|
|
29
29
|
class Operation
|
30
|
-
include Dry::Monads::Maybe::Mixin
|
31
30
|
include Dry::Monads::Do.for(:call)
|
32
31
|
|
33
32
|
def call
|
@@ -59,40 +58,21 @@ namespace :perf do
|
|
59
58
|
|
60
59
|
# Contains internal benchmarking to if optimization works
|
61
60
|
namespace :fear do
|
62
|
-
task :fear_pattern_extracting_with_vs_without_cache do
|
63
|
-
some = Fear.some([:err, "not found"])
|
64
|
-
|
65
|
-
class WOCache < Fear::Extractor::Pattern
|
66
|
-
def initialize(pattern)
|
67
|
-
@matcher = compile_pattern_without_cache(pattern)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
pattern = "Fear::Some([:err, code])"
|
71
|
-
|
72
|
-
Benchmark.ips do |x|
|
73
|
-
x.report("With cache") do |_n|
|
74
|
-
Fear::Extractor::Pattern.new(pattern).extracted_arguments(some)
|
75
|
-
end
|
76
|
-
|
77
|
-
x.report("Without cache") do |_n|
|
78
|
-
WOCache.new(pattern).extracted_arguments(some)
|
79
|
-
end
|
80
|
-
|
81
|
-
x.compare!
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
61
|
namespace :guard do
|
86
62
|
task :and1_vs_new do
|
87
|
-
|
63
|
+
iterations = 1_000
|
88
64
|
|
89
65
|
Benchmark.ips do |x|
|
90
66
|
x.report("Guard.new") do |n|
|
91
|
-
|
67
|
+
iterations.times do
|
68
|
+
Fear::PartialFunction::Guard.new(Integer) === n
|
69
|
+
end
|
92
70
|
end
|
93
71
|
|
94
72
|
x.report("Guard.and1") do |n|
|
95
|
-
|
73
|
+
iterations.times do
|
74
|
+
Fear::PartialFunction::Guard.and1(Integer) === n
|
75
|
+
end
|
96
76
|
end
|
97
77
|
|
98
78
|
x.compare!
|
@@ -100,6 +80,7 @@ namespace :perf do
|
|
100
80
|
end
|
101
81
|
|
102
82
|
task :and2_vs_and do
|
83
|
+
iterations = 1_000
|
103
84
|
first = Integer
|
104
85
|
second = ->(x) { x > 2 }
|
105
86
|
|
@@ -108,11 +89,11 @@ namespace :perf do
|
|
108
89
|
|
109
90
|
Benchmark.ips do |x|
|
110
91
|
x.report("and2") do |n|
|
111
|
-
and2 === n
|
92
|
+
iterations.times { and2 === n }
|
112
93
|
end
|
113
94
|
|
114
95
|
x.report("Guard#and") do |n|
|
115
|
-
and_and === n
|
96
|
+
iterations.times { and_and === n }
|
116
97
|
end
|
117
98
|
|
118
99
|
x.compare!
|
@@ -120,6 +101,7 @@ namespace :perf do
|
|
120
101
|
end
|
121
102
|
|
122
103
|
task :and3_vs_and_and do
|
104
|
+
iterations = 1_000
|
123
105
|
first = Integer
|
124
106
|
second = ->(x) { x > 2 }
|
125
107
|
third = ->(x) { x < 10 }
|
@@ -132,11 +114,11 @@ namespace :perf do
|
|
132
114
|
|
133
115
|
Benchmark.ips do |x|
|
134
116
|
x.report("Guard.and3") do |n|
|
135
|
-
and3 === n
|
117
|
+
iterations.times { and3 === n }
|
136
118
|
end
|
137
119
|
|
138
120
|
x.report("Guard#and") do |n|
|
139
|
-
and_and_and === n
|
121
|
+
iterations.times { and_and_and === n }
|
140
122
|
end
|
141
123
|
|
142
124
|
x.compare!
|
@@ -165,16 +147,17 @@ namespace :perf do
|
|
165
147
|
x.compare!
|
166
148
|
end
|
167
149
|
end
|
168
|
-
end
|
169
|
-
|
170
|
-
namespace :pattern_matching do
|
171
|
-
require "qo"
|
172
|
-
require "dry/matcher"
|
173
150
|
|
174
151
|
task :option_match_vs_native_pattern_match do
|
175
152
|
some = Fear.some(42)
|
176
153
|
|
177
154
|
Benchmark.ips do |x|
|
155
|
+
matcher = Fear::Option.matcher do |m|
|
156
|
+
m.some(41, &:itself)
|
157
|
+
m.some(42, &:itself)
|
158
|
+
m.some(45, &:itself)
|
159
|
+
end
|
160
|
+
|
178
161
|
x.report("case ... in ...") do
|
179
162
|
case some
|
180
163
|
in Fear::Some(41 => x)
|
@@ -186,7 +169,7 @@ namespace :perf do
|
|
186
169
|
end
|
187
170
|
end
|
188
171
|
|
189
|
-
x.report("Option
|
172
|
+
x.report("Option#match") do
|
190
173
|
some.match do |m|
|
191
174
|
m.some(41, &:itself)
|
192
175
|
m.some(42, &:itself)
|
@@ -194,27 +177,19 @@ namespace :perf do
|
|
194
177
|
end
|
195
178
|
end
|
196
179
|
|
180
|
+
x.report("Option#matcher") do
|
181
|
+
matcher.(some)
|
182
|
+
end
|
183
|
+
|
197
184
|
x.compare!
|
198
185
|
end
|
199
186
|
end
|
187
|
+
end
|
200
188
|
|
201
|
-
|
202
|
-
|
203
|
-
def initialize(*)
|
204
|
-
super
|
205
|
-
@default ||= self.else { raise Fear::MatchError }
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
|
210
|
-
FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
|
211
|
-
|
212
|
-
PatternMatch = Qo.create_pattern_match(
|
213
|
-
branches: [SuccessBranch, FailureBranch],
|
214
|
-
).prepend(ExhaustivePatternMatch)
|
215
|
-
|
216
|
-
Fear::Success.include(PatternMatch.mixin(as: :qo_match))
|
189
|
+
namespace :pattern_matching do
|
190
|
+
require "dry/matcher"
|
217
191
|
|
192
|
+
task :dry_vs_fear_try do
|
218
193
|
success_case = Dry::Matcher::Case.new(
|
219
194
|
match: ->(try, *pattern) {
|
220
195
|
try.is_a?(Fear::Success) && pattern.all? { |p| p === try.get }
|
@@ -235,14 +210,6 @@ namespace :perf do
|
|
235
210
|
success = Fear::Success.new(4)
|
236
211
|
|
237
212
|
Benchmark.ips do |x|
|
238
|
-
x.report("Qo") do
|
239
|
-
success.qo_match do |m|
|
240
|
-
m.failure(&:itself)
|
241
|
-
m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
|
242
|
-
m.success { "else" }
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
213
|
x.report("Fear") do
|
247
214
|
success.match do |m|
|
248
215
|
m.failure(&:itself)
|
@@ -263,50 +230,6 @@ namespace :perf do
|
|
263
230
|
end
|
264
231
|
end
|
265
232
|
|
266
|
-
task :qo_vs_fear_try_execution do
|
267
|
-
module ExhaustivePatternMatch
|
268
|
-
def initialize(*)
|
269
|
-
super
|
270
|
-
@default ||= self.else { raise Fear::MatchError }
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
|
275
|
-
FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
|
276
|
-
|
277
|
-
QoPatternMatch = Qo.create_pattern_match(
|
278
|
-
branches: [SuccessBranch, FailureBranch],
|
279
|
-
).prepend(ExhaustivePatternMatch)
|
280
|
-
|
281
|
-
Fear::Success.include(QoPatternMatch.mixin(as: :qo_match))
|
282
|
-
|
283
|
-
success = Fear::Success.new(4)
|
284
|
-
|
285
|
-
qo_matcher = QoPatternMatch.new do |m|
|
286
|
-
m.success(1, &:itself)
|
287
|
-
m.success(4, &:itself)
|
288
|
-
m.failure { "failure" }
|
289
|
-
end
|
290
|
-
|
291
|
-
fear_matcher = Fear::TryPatternMatch.new do |m|
|
292
|
-
m.success(1, &:itself)
|
293
|
-
m.success(4, &:itself)
|
294
|
-
m.failure { "failure" }
|
295
|
-
end
|
296
|
-
|
297
|
-
Benchmark.ips do |x|
|
298
|
-
x.report("Qo") do
|
299
|
-
qo_matcher.(success)
|
300
|
-
end
|
301
|
-
|
302
|
-
x.report("Fear") do
|
303
|
-
fear_matcher.(success)
|
304
|
-
end
|
305
|
-
|
306
|
-
x.compare!
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
233
|
task :factorial do
|
311
234
|
factorial_proc = proc do |n|
|
312
235
|
if n <= 1
|
@@ -322,12 +245,6 @@ namespace :perf do
|
|
322
245
|
m.else { |n| n * factorial_pm.(n - 1) }
|
323
246
|
end
|
324
247
|
|
325
|
-
factorial_qo = Qo.match do |m|
|
326
|
-
m.when(1, &:itself)
|
327
|
-
m.when(0, &:itself)
|
328
|
-
m.else { |n| n * factorial_qo.(n - 1) }
|
329
|
-
end
|
330
|
-
|
331
248
|
Benchmark.ips do |x|
|
332
249
|
x.report("Proc") do
|
333
250
|
factorial_proc.(100)
|
@@ -337,10 +254,6 @@ namespace :perf do
|
|
337
254
|
factorial_pm.(100)
|
338
255
|
end
|
339
256
|
|
340
|
-
x.report("Qo") do
|
341
|
-
factorial_qo.(100)
|
342
|
-
end
|
343
|
-
|
344
257
|
x.compare!
|
345
258
|
end
|
346
259
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
> bundle exec rake perf:dry:do_vs_fear_for
|
2
|
+
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
|
2
3
|
Warming up --------------------------------------
|
3
|
-
Dry
|
4
|
-
Fear
|
4
|
+
Dry 50.838k i/100ms
|
5
|
+
Fear 53.687T i/100ms
|
5
6
|
Calculating -------------------------------------
|
6
|
-
Dry
|
7
|
-
Fear
|
7
|
+
Dry 505.586k (± 1.3%) i/s - 2.542M in 5.028546s
|
8
|
+
Fear 38414118363278401536.000 (±35.1%) i/s - 129350402624716800000.000 in 4.237227s
|
8
9
|
|
9
10
|
Comparison:
|
10
|
-
Fear:
|
11
|
-
Dry:
|
11
|
+
Fear: 38414118363278401536.0 i/s
|
12
|
+
Dry: 505586.3 i/s - 75979343079241.66x slower
|
@@ -1,11 +1,12 @@
|
|
1
1
|
> bundle exec rake perf:dry:some_fmap_vs_fear_some_map
|
2
|
+
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
|
2
3
|
Warming up --------------------------------------
|
3
|
-
Dry
|
4
|
-
Fear
|
4
|
+
Dry 156.108k i/100ms
|
5
|
+
Fear 398.884k i/100ms
|
5
6
|
Calculating -------------------------------------
|
6
|
-
Dry
|
7
|
-
Fear
|
7
|
+
Dry 1.561M (± 0.2%) i/s - 7.962M in 5.099636s
|
8
|
+
Fear 3.976M (± 0.5%) i/s - 19.944M in 5.016186s
|
8
9
|
|
9
10
|
Comparison:
|
10
|
-
Fear:
|
11
|
-
Dry:
|
11
|
+
Fear: 3976079.7 i/s
|
12
|
+
Dry: 1561199.0 i/s - 2.55x slower
|
data/benchmarks/factorial.txt
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
# Depends on `n`, for 100!:
|
2
2
|
|
3
3
|
> bundle exec rake perf:pattern_matching:factorial
|
4
|
+
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
|
4
5
|
Warming up --------------------------------------
|
5
|
-
Proc
|
6
|
-
Fear
|
7
|
-
Qo 122.000 i/100ms
|
6
|
+
Proc 5.678k i/100ms
|
7
|
+
Fear 859.000 i/100ms
|
8
8
|
Calculating -------------------------------------
|
9
|
-
Proc
|
10
|
-
Fear
|
11
|
-
Qo 1.250k (± 4.8%) i/s - 6.344k in 5.090745s
|
9
|
+
Proc 56.634k (± 0.2%) i/s - 283.900k in 5.012921s
|
10
|
+
Fear 8.573k (± 0.5%) i/s - 42.950k in 5.009859s
|
12
11
|
|
13
12
|
Comparison:
|
14
|
-
Proc:
|
15
|
-
Fear:
|
16
|
-
Qo: 1249.6 i/s - 21.30x slower
|
13
|
+
Proc: 56633.8 i/s
|
14
|
+
Fear: 8573.3 i/s - 6.61x slower
|