fear 0.10.0 → 0.11.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/.rubocop.yml +30 -4
- data/.travis.yml +2 -3
- data/Appraisals +5 -9
- data/CHANGELOG.md +9 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +255 -85
- data/Rakefile +393 -0
- data/fear.gemspec +13 -6
- data/gemfiles/dry_equalizer_0.1.0.gemfile +1 -0
- data/gemfiles/dry_equalizer_0.1.0.gemfile.lock +31 -27
- data/gemfiles/dry_equalizer_0.2.1.gemfile +1 -0
- data/gemfiles/dry_equalizer_0.2.1.gemfile.lock +31 -27
- data/lib/fear/either.rb +49 -14
- data/lib/fear/either_pattern_match.rb +48 -0
- data/lib/fear/empty_partial_function.rb +36 -0
- data/lib/fear/failure.rb +5 -4
- data/lib/fear/failure_pattern_match.rb +8 -0
- data/lib/fear/for.rb +46 -51
- data/lib/fear/left.rb +7 -1
- data/lib/fear/left_pattern_match.rb +9 -0
- data/lib/fear/none.rb +37 -2
- data/lib/fear/none_pattern_match.rb +12 -0
- data/lib/fear/option.rb +65 -31
- data/lib/fear/option_pattern_match.rb +45 -0
- data/lib/fear/partial_function/and_then.rb +48 -0
- data/lib/fear/partial_function/any.rb +26 -0
- data/lib/fear/partial_function/combined.rb +51 -0
- data/lib/fear/partial_function/empty.rb +6 -0
- data/lib/fear/partial_function/guard/and.rb +36 -0
- data/lib/fear/partial_function/guard/and3.rb +39 -0
- data/lib/fear/partial_function/guard/or.rb +36 -0
- data/lib/fear/partial_function/guard.rb +90 -0
- data/lib/fear/partial_function/lifted.rb +20 -0
- data/lib/fear/partial_function/or_else.rb +62 -0
- data/lib/fear/partial_function.rb +171 -0
- data/lib/fear/partial_function_class.rb +26 -0
- data/lib/fear/pattern_match.rb +102 -0
- data/lib/fear/pattern_matching_api.rb +110 -0
- data/lib/fear/right.rb +7 -1
- data/lib/fear/right_biased.rb +2 -12
- data/lib/fear/right_pattern_match.rb +9 -0
- data/lib/fear/some.rb +5 -2
- data/lib/fear/some_pattern_match.rb +11 -0
- data/lib/fear/success.rb +5 -4
- data/lib/fear/success_pattern_match.rb +10 -0
- data/lib/fear/try.rb +56 -16
- data/lib/fear/try_pattern_match.rb +28 -0
- data/lib/fear/utils.rb +24 -14
- data/lib/fear/version.rb +1 -1
- data/lib/fear.rb +21 -4
- data/spec/fear/either_pattern_match_spec.rb +37 -0
- data/spec/fear/failure_spec.rb +41 -3
- data/spec/fear/for_spec.rb +17 -29
- data/spec/fear/guard_spec.rb +101 -0
- data/spec/fear/left_spec.rb +38 -0
- data/spec/fear/none_spec.rb +80 -0
- data/spec/fear/option_pattern_match_spec.rb +35 -0
- data/spec/fear/partial_function/empty_spec.rb +36 -0
- data/spec/fear/partial_function_and_then_spec.rb +145 -0
- data/spec/fear/partial_function_composition_spec.rb +80 -0
- data/spec/fear/partial_function_or_else_spec.rb +274 -0
- data/spec/fear/partial_function_spec.rb +165 -0
- data/spec/fear/pattern_match_spec.rb +59 -0
- data/spec/fear/right_biased/left.rb +1 -6
- data/spec/fear/right_biased/right.rb +0 -5
- data/spec/fear/right_spec.rb +38 -0
- data/spec/fear/some_spec.rb +37 -0
- data/spec/fear/success_spec.rb +41 -4
- data/spec/fear/try_pattern_match_spec.rb +37 -0
- metadata +97 -23
- data/lib/fear/for/evaluation_context.rb +0 -91
@@ -0,0 +1,59 @@
|
|
1
|
+
RSpec.describe Fear::PatternMatch do
|
2
|
+
include Fear::Option::Mixin
|
3
|
+
|
4
|
+
context 'else at the end' do
|
5
|
+
let(:matcher) do
|
6
|
+
described_class.new do |m|
|
7
|
+
m.case(Integer) { |x| "#{x} is int" }
|
8
|
+
m.case(String) { |x| "#{x} is str" }
|
9
|
+
m.else { |x| "#{x} is something else" }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'Integer' do
|
14
|
+
subject { matcher.call(4) }
|
15
|
+
|
16
|
+
it { is_expected.to eq('4 is int') }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'String' do
|
20
|
+
subject { matcher.call('4') }
|
21
|
+
|
22
|
+
it { is_expected.to eq('4 is str') }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'Symbol' do
|
26
|
+
subject { matcher.call(:a) }
|
27
|
+
|
28
|
+
it { is_expected.to eq('a is something else') }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'else before other branches' do
|
33
|
+
subject { matcher.call(4) }
|
34
|
+
|
35
|
+
let(:matcher) do
|
36
|
+
described_class.new do |m|
|
37
|
+
m.else { |x| "#{x} is something else" }
|
38
|
+
m.case(Integer) { |x| "#{x} is int" }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it { is_expected.to eq('4 is something else') }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'several else branches' do
|
46
|
+
subject { matcher.call(4) }
|
47
|
+
|
48
|
+
let(:matcher) do
|
49
|
+
described_class.new do |m|
|
50
|
+
m.else { |x| "#{x} else 1" }
|
51
|
+
m.else { |x| "#{x} else 2" }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'first one wins' do
|
56
|
+
is_expected.to eq('4 else 1')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -66,14 +66,9 @@ RSpec.shared_examples Fear::RightBiased::Left do
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
describe '#to_a' do
|
70
|
-
subject { left.to_a }
|
71
|
-
it { is_expected.to eq([]) }
|
72
|
-
end
|
73
|
-
|
74
69
|
describe '#to_option' do
|
75
70
|
subject { left.to_option }
|
76
|
-
it { is_expected.to eq(Fear::None
|
71
|
+
it { is_expected.to eq(Fear::None) }
|
77
72
|
end
|
78
73
|
|
79
74
|
describe '#any?' do
|
@@ -93,11 +93,6 @@ RSpec.shared_examples Fear::RightBiased::Right do
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
describe '#to_a' do
|
97
|
-
subject { right.to_a }
|
98
|
-
it { is_expected.to eq(['value']) }
|
99
|
-
end
|
100
|
-
|
101
96
|
describe '#to_option' do
|
102
97
|
subject { right.to_option }
|
103
98
|
it { is_expected.to eq(Fear::Some.new('value')) }
|
data/spec/fear/right_spec.rb
CHANGED
@@ -114,4 +114,42 @@ RSpec.describe Fear::Right do
|
|
114
114
|
it { is_expected.to eq(either) }
|
115
115
|
end
|
116
116
|
end
|
117
|
+
|
118
|
+
describe '#match' do
|
119
|
+
context 'matched' do
|
120
|
+
subject do
|
121
|
+
right.match do |m|
|
122
|
+
m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
|
123
|
+
m.right(->(x) { x.length > 2 }) { |x| "Right: #{x}" }
|
124
|
+
m.left(->(x) { x.length > 2 }) { |x| "Left: #{x}" }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it { is_expected.to eq('Right: value') }
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'nothing matched and no else given' do
|
132
|
+
subject do
|
133
|
+
proc do
|
134
|
+
right.match do |m|
|
135
|
+
m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
|
136
|
+
m.left { |_| 'noop' }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it { is_expected.to raise_error(Fear::MatchError) }
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'nothing matched and else given' do
|
145
|
+
subject do
|
146
|
+
right.match do |m|
|
147
|
+
m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
|
148
|
+
m.else { :default }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it { is_expected.to eq(:default) }
|
153
|
+
end
|
154
|
+
end
|
117
155
|
end
|
data/spec/fear/some_spec.rb
CHANGED
@@ -49,4 +49,41 @@ RSpec.describe Fear::Some do
|
|
49
49
|
subject { some.empty? }
|
50
50
|
it { is_expected.to eq(false) }
|
51
51
|
end
|
52
|
+
|
53
|
+
describe '#match' do
|
54
|
+
context 'matched' do
|
55
|
+
subject do
|
56
|
+
some.match do |m|
|
57
|
+
m.some(->(x) { x > 2 }) { |x| x * 2 }
|
58
|
+
m.none { 'noop' }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it { is_expected.to eq(84) }
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'nothing matched and no else given' do
|
66
|
+
subject do
|
67
|
+
proc do
|
68
|
+
some.match do |m|
|
69
|
+
m.some(->(x) { x < 2 }) { |x| x * 2 }
|
70
|
+
m.none { 'noop' }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it { is_expected.to raise_error(Fear::MatchError) }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'nothing matched and else given' do
|
79
|
+
subject do
|
80
|
+
some.match do |m|
|
81
|
+
m.none { |x| x * 2 }
|
82
|
+
m.else { :default }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it { is_expected.to eq(:default) }
|
87
|
+
end
|
88
|
+
end
|
52
89
|
end
|
data/spec/fear/success_spec.rb
CHANGED
@@ -5,14 +5,14 @@ RSpec.describe Fear::Success do
|
|
5
5
|
let(:right) { success }
|
6
6
|
|
7
7
|
describe '#map', 'block fails' do
|
8
|
-
subject(:map) { right.map {
|
8
|
+
subject(:map) { right.map { raise 'unexpected error' } }
|
9
9
|
|
10
10
|
it { is_expected.to be_kind_of(Fear::Failure) }
|
11
11
|
it { expect { map.get }.to raise_error(RuntimeError, 'unexpected error') }
|
12
12
|
end
|
13
13
|
|
14
14
|
describe '#flat_map', 'block fails' do
|
15
|
-
subject(:flat_map) { right.flat_map {
|
15
|
+
subject(:flat_map) { right.flat_map { raise 'unexpected error' } }
|
16
16
|
|
17
17
|
it { is_expected.to be_kind_of(Fear::Failure) }
|
18
18
|
it { expect { flat_map.get }.to raise_error(RuntimeError, 'unexpected error') }
|
@@ -66,12 +66,12 @@ RSpec.describe Fear::Success do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
context 'predicate does not hold for value' do
|
69
|
-
subject { proc { success.select { |v| v != 'value' }.get } }
|
69
|
+
subject { proc { success.select { |v| v != 'value' }.get } } # rubocop: disable Style/InverseMethods
|
70
70
|
it { is_expected.to raise_error(Fear::NoSuchElementError, 'Predicate does not hold for `value`') }
|
71
71
|
end
|
72
72
|
|
73
73
|
context 'predicate fails with error' do
|
74
|
-
subject { proc { success.select {
|
74
|
+
subject { proc { success.select { raise 'foo' }.get } }
|
75
75
|
it { is_expected.to raise_error(RuntimeError, 'foo') }
|
76
76
|
end
|
77
77
|
end
|
@@ -90,4 +90,41 @@ RSpec.describe Fear::Success do
|
|
90
90
|
subject { success.to_either }
|
91
91
|
it { is_expected.to eq(Right('value')) }
|
92
92
|
end
|
93
|
+
|
94
|
+
describe '#match' do
|
95
|
+
context 'matched' do
|
96
|
+
subject do
|
97
|
+
success.match do |m|
|
98
|
+
m.success(->(x) { x.length > 2 }) { |x| x * 2 }
|
99
|
+
m.failure { 'noop' }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it { is_expected.to eq('valuevalue') }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'nothing matched and no else given' do
|
107
|
+
subject do
|
108
|
+
proc do
|
109
|
+
success.match do |m|
|
110
|
+
m.success(->(x) { x.length < 2 }) { |x| x * 2 }
|
111
|
+
m.failure { 'noop' }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it { is_expected.to raise_error(Fear::MatchError) }
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'nothing matched and else given' do
|
120
|
+
subject do
|
121
|
+
success.match do |m|
|
122
|
+
m.failure { |x| x * 2 }
|
123
|
+
m.else { :default }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it { is_expected.to eq(:default) }
|
128
|
+
end
|
129
|
+
end
|
93
130
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
RSpec.describe Fear::TryPatternMatch do
|
2
|
+
include Fear::Try::Mixin
|
3
|
+
|
4
|
+
context 'Success' do
|
5
|
+
let(:matcher) do
|
6
|
+
described_class.new do |m|
|
7
|
+
m.success(:even?) { |x| "#{x} is even" }
|
8
|
+
m.success(:odd?) { |x| "#{x} is odd" }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it do
|
13
|
+
expect(matcher.call(Success(4))).to eq('4 is even')
|
14
|
+
expect(matcher.call(Success(3))).to eq('3 is odd')
|
15
|
+
expect do
|
16
|
+
matcher.call(Failure(RuntimeError.new))
|
17
|
+
end.to raise_error(Fear::MatchError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'Failure' do
|
22
|
+
let(:matcher) do
|
23
|
+
described_class.new do |m|
|
24
|
+
m.failure(RuntimeError) { |x| "#{x} is first" }
|
25
|
+
m.failure(StandardError) { |x| "#{x} is second" }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it do
|
30
|
+
expect(matcher.call(Failure(RuntimeError.new))).to eq('RuntimeError is first')
|
31
|
+
expect(matcher.call(Failure(StandardError.new))).to eq('StandardError is second')
|
32
|
+
expect do
|
33
|
+
matcher.call(Success(44))
|
34
|
+
end.to raise_error(Fear::MatchError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fear
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tema Bolshakov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-equalizer
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: benchmark-ips
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,34 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dry-matcher
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: qo
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: rake
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,44 +128,30 @@ dependencies:
|
|
86
128
|
requirements:
|
87
129
|
- - '='
|
88
130
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
131
|
+
version: 0.65.0
|
90
132
|
type: :development
|
91
133
|
prerelease: false
|
92
134
|
version_requirements: !ruby/object:Gem::Requirement
|
93
135
|
requirements:
|
94
136
|
- - '='
|
95
137
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
138
|
+
version: 0.65.0
|
97
139
|
- !ruby/object:Gem::Dependency
|
98
140
|
name: rubocop-rspec
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
100
142
|
requirements:
|
101
143
|
- - '='
|
102
144
|
- !ruby/object:Gem::Version
|
103
|
-
version: 1.
|
145
|
+
version: 1.32.0
|
104
146
|
type: :development
|
105
147
|
prerelease: false
|
106
148
|
version_requirements: !ruby/object:Gem::Requirement
|
107
149
|
requirements:
|
108
150
|
- - '='
|
109
151
|
- !ruby/object:Gem::Version
|
110
|
-
version: 1.
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: simplecov
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
152
|
+
version: 1.32.0
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
154
|
+
name: yard
|
127
155
|
requirement: !ruby/object:Gem::Requirement
|
128
156
|
requirements:
|
129
157
|
- - ">="
|
@@ -162,37 +190,73 @@ files:
|
|
162
190
|
- lib/fear.rb
|
163
191
|
- lib/fear/done.rb
|
164
192
|
- lib/fear/either.rb
|
193
|
+
- lib/fear/either_pattern_match.rb
|
194
|
+
- lib/fear/empty_partial_function.rb
|
165
195
|
- lib/fear/failure.rb
|
196
|
+
- lib/fear/failure_pattern_match.rb
|
166
197
|
- lib/fear/for.rb
|
167
|
-
- lib/fear/for/evaluation_context.rb
|
168
198
|
- lib/fear/left.rb
|
199
|
+
- lib/fear/left_pattern_match.rb
|
169
200
|
- lib/fear/none.rb
|
201
|
+
- lib/fear/none_pattern_match.rb
|
170
202
|
- lib/fear/option.rb
|
203
|
+
- lib/fear/option_pattern_match.rb
|
204
|
+
- lib/fear/partial_function.rb
|
205
|
+
- lib/fear/partial_function/and_then.rb
|
206
|
+
- lib/fear/partial_function/any.rb
|
207
|
+
- lib/fear/partial_function/combined.rb
|
208
|
+
- lib/fear/partial_function/empty.rb
|
209
|
+
- lib/fear/partial_function/guard.rb
|
210
|
+
- lib/fear/partial_function/guard/and.rb
|
211
|
+
- lib/fear/partial_function/guard/and3.rb
|
212
|
+
- lib/fear/partial_function/guard/or.rb
|
213
|
+
- lib/fear/partial_function/lifted.rb
|
214
|
+
- lib/fear/partial_function/or_else.rb
|
215
|
+
- lib/fear/partial_function_class.rb
|
216
|
+
- lib/fear/pattern_match.rb
|
217
|
+
- lib/fear/pattern_matching_api.rb
|
171
218
|
- lib/fear/right.rb
|
172
219
|
- lib/fear/right_biased.rb
|
220
|
+
- lib/fear/right_pattern_match.rb
|
173
221
|
- lib/fear/some.rb
|
222
|
+
- lib/fear/some_pattern_match.rb
|
174
223
|
- lib/fear/success.rb
|
224
|
+
- lib/fear/success_pattern_match.rb
|
175
225
|
- lib/fear/try.rb
|
226
|
+
- lib/fear/try_pattern_match.rb
|
176
227
|
- lib/fear/utils.rb
|
177
228
|
- lib/fear/version.rb
|
178
229
|
- spec/fear/done_spec.rb
|
230
|
+
- spec/fear/either_pattern_match_spec.rb
|
179
231
|
- spec/fear/failure_spec.rb
|
180
232
|
- spec/fear/for_spec.rb
|
233
|
+
- spec/fear/guard_spec.rb
|
181
234
|
- spec/fear/left_spec.rb
|
182
235
|
- spec/fear/none_spec.rb
|
236
|
+
- spec/fear/option_pattern_match_spec.rb
|
183
237
|
- spec/fear/option_spec.rb
|
238
|
+
- spec/fear/partial_function/empty_spec.rb
|
239
|
+
- spec/fear/partial_function_and_then_spec.rb
|
240
|
+
- spec/fear/partial_function_composition_spec.rb
|
241
|
+
- spec/fear/partial_function_or_else_spec.rb
|
242
|
+
- spec/fear/partial_function_spec.rb
|
243
|
+
- spec/fear/pattern_match_spec.rb
|
184
244
|
- spec/fear/right_biased/left.rb
|
185
245
|
- spec/fear/right_biased/right.rb
|
186
246
|
- spec/fear/right_spec.rb
|
187
247
|
- spec/fear/some_spec.rb
|
188
248
|
- spec/fear/success_spec.rb
|
249
|
+
- spec/fear/try_pattern_match_spec.rb
|
189
250
|
- spec/fear/utils_spec.rb
|
190
251
|
- spec/spec_helper.rb
|
191
252
|
homepage: https://github.com/bolshakov/fear
|
192
253
|
licenses:
|
193
254
|
- MIT
|
194
255
|
metadata: {}
|
195
|
-
post_install_message:
|
256
|
+
post_install_message: |2
|
257
|
+
Fear v0.11.0 introduces backwards-incompatible changes.
|
258
|
+
Please see https://github.com/bolshakov/fear/blob/master/CHANGELOG.md#0110 for details.
|
259
|
+
Successfully installed fear-0.11.0
|
196
260
|
rdoc_options: []
|
197
261
|
require_paths:
|
198
262
|
- lib
|
@@ -214,15 +278,25 @@ specification_version: 4
|
|
214
278
|
summary: "%q{Ruby port of some Scala's monads.}"
|
215
279
|
test_files:
|
216
280
|
- spec/fear/done_spec.rb
|
281
|
+
- spec/fear/either_pattern_match_spec.rb
|
217
282
|
- spec/fear/failure_spec.rb
|
218
283
|
- spec/fear/for_spec.rb
|
284
|
+
- spec/fear/guard_spec.rb
|
219
285
|
- spec/fear/left_spec.rb
|
220
286
|
- spec/fear/none_spec.rb
|
287
|
+
- spec/fear/option_pattern_match_spec.rb
|
221
288
|
- spec/fear/option_spec.rb
|
289
|
+
- spec/fear/partial_function/empty_spec.rb
|
290
|
+
- spec/fear/partial_function_and_then_spec.rb
|
291
|
+
- spec/fear/partial_function_composition_spec.rb
|
292
|
+
- spec/fear/partial_function_or_else_spec.rb
|
293
|
+
- spec/fear/partial_function_spec.rb
|
294
|
+
- spec/fear/pattern_match_spec.rb
|
222
295
|
- spec/fear/right_biased/left.rb
|
223
296
|
- spec/fear/right_biased/right.rb
|
224
297
|
- spec/fear/right_spec.rb
|
225
298
|
- spec/fear/some_spec.rb
|
226
299
|
- spec/fear/success_spec.rb
|
300
|
+
- spec/fear/try_pattern_match_spec.rb
|
227
301
|
- spec/fear/utils_spec.rb
|
228
302
|
- spec/spec_helper.rb
|
@@ -1,91 +0,0 @@
|
|
1
|
-
module Fear
|
2
|
-
# This class provides syntactic sugar for composition of
|
3
|
-
# multiple monadic operations. It supports two such
|
4
|
-
# operations - +flat_map+ and +map+. Any class providing them
|
5
|
-
# is supported by +For+.
|
6
|
-
#
|
7
|
-
# For(a: Some(2), b: Some(3)) { a * b } #=> Some(6)
|
8
|
-
#
|
9
|
-
# If one of operands is None, the result is None
|
10
|
-
#
|
11
|
-
# For(a: Some(2), b: None()) { a * b } #=> None()
|
12
|
-
# For(a: None(), b: Some(2)) { a * b } #=> None()
|
13
|
-
#
|
14
|
-
# Lets look at first example:
|
15
|
-
#
|
16
|
-
# For(a: Some(2), b: Some(3)) { a * b }
|
17
|
-
#
|
18
|
-
# would be translated to:
|
19
|
-
#
|
20
|
-
# Some(2).flat_map do |a|
|
21
|
-
# Some(3).map do |b|
|
22
|
-
# a * b
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# It works with arrays as well
|
27
|
-
#
|
28
|
-
# For(a: [1, 2], b: [2, 3], c: [3, 4]) { a * b * c }
|
29
|
-
# #=> [6, 8, 9, 12, 12, 16, 18, 24]
|
30
|
-
#
|
31
|
-
# would be translated to:
|
32
|
-
#
|
33
|
-
# [1, 2].flat_map do |a|
|
34
|
-
# [2, 3].flat_map do |b|
|
35
|
-
# [3, 4].map do |c|
|
36
|
-
# a * b * c
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# If you pass lambda as a variable value, it would be evaluated
|
42
|
-
# only on demand.
|
43
|
-
#
|
44
|
-
# For(a: -> { None() }, b: -> { fail 'kaboom' } ) { a * b }
|
45
|
-
# #=> None()
|
46
|
-
#
|
47
|
-
# It does not fail since `b` is not evaluated.
|
48
|
-
# You can mix and match lambdas and variables.
|
49
|
-
#
|
50
|
-
# For(a: -> None(), b: -> { fail 'kaboom' } ) { a * b }
|
51
|
-
# #=> None()
|
52
|
-
#
|
53
|
-
class For
|
54
|
-
# Context of block evaluation. It respond to passed locals.
|
55
|
-
#
|
56
|
-
# @example
|
57
|
-
# context = EvaluationContext.new
|
58
|
-
# context.assign(:foo, 'bar')
|
59
|
-
# context.foo #=> 'bar'
|
60
|
-
#
|
61
|
-
class EvaluationContext < BasicObject
|
62
|
-
include ::Fear::Option::Mixin
|
63
|
-
include ::Fear::Either::Mixin
|
64
|
-
include ::Fear::Try::Mixin
|
65
|
-
|
66
|
-
def initialize(outer_context)
|
67
|
-
@assigns = {}
|
68
|
-
@outer_context = outer_context
|
69
|
-
end
|
70
|
-
|
71
|
-
def __assign__(name, value)
|
72
|
-
@assigns[name] = value
|
73
|
-
end
|
74
|
-
|
75
|
-
def method_missing(name, *args, &block)
|
76
|
-
if @assigns.include?(name) && args.empty? && block.nil?
|
77
|
-
@assigns[name]
|
78
|
-
elsif @outer_context.respond_to?(name, true)
|
79
|
-
@outer_context.__send__(name, *args, &block)
|
80
|
-
else
|
81
|
-
super
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def respond_to_missing?(name, _)
|
86
|
-
@assigns.key?(name) && args.empty? && block.nil?
|
87
|
-
end
|
88
|
-
end
|
89
|
-
private_constant(:EvaluationContext)
|
90
|
-
end
|
91
|
-
end
|