either 0.0.1 → 0.0.2
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.
- data/.travis.yml +6 -0
- data/Gemfile.lock +2 -0
- data/README.md +2 -0
- data/either.gemspec +3 -1
- data/lib/either.rb +10 -0
- data/lib/either/match.rb +74 -0
- data/lib/left.rb +31 -0
- data/lib/right.rb +32 -0
- data/spec/lib/either/match_spec.rb +21 -0
- data/spec/lib/either_spec.rb +15 -0
- data/spec/lib/left_spec.rb +27 -0
- data/spec/lib/right_spec.rb +27 -0
- metadata +34 -4
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/README.md
ADDED
data/either.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'either'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.2'
|
4
4
|
s.date = '2013-07-10'
|
5
5
|
s.summary = "Either types with pattern matching"
|
6
6
|
s.description = "Stop using exceptions for control flow!"
|
@@ -10,7 +10,9 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
11
11
|
s.require_paths = ["lib"]
|
12
12
|
s.homepage = 'http://github.com/rsslldnphy/either'
|
13
|
+
s.license = 'MIT'
|
13
14
|
|
15
|
+
s.add_runtime_dependency "optional"
|
14
16
|
s.add_development_dependency "rake"
|
15
17
|
s.add_development_dependency "rspec"
|
16
18
|
s.add_development_dependency "simplecov"
|
data/lib/either.rb
ADDED
data/lib/either/match.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Either
|
2
|
+
class Match
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@lefts = []
|
6
|
+
@rights = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def left pattern=always, &block
|
10
|
+
@lefts << [(lambify pattern), block]
|
11
|
+
end
|
12
|
+
|
13
|
+
def right pattern=always, &block
|
14
|
+
@rights << [(lambify pattern), block]
|
15
|
+
end
|
16
|
+
|
17
|
+
def evaluate(either)
|
18
|
+
Evaluation.new(self, either).result
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :lefts, :rights
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def lambify(pattern)
|
26
|
+
pattern.is_a?(Proc) ? pattern : ->(x){ x == pattern }
|
27
|
+
end
|
28
|
+
|
29
|
+
def always
|
30
|
+
->(x) { true }
|
31
|
+
end
|
32
|
+
|
33
|
+
class Evaluation
|
34
|
+
|
35
|
+
def initialize(match, either)
|
36
|
+
@match = match
|
37
|
+
@either = either
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :match, :either
|
41
|
+
|
42
|
+
def result
|
43
|
+
either.left? ? left_result : right_result
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def left_result
|
49
|
+
left_match.call(either.left.value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def right_result
|
53
|
+
right_match.call(either.right.value)
|
54
|
+
end
|
55
|
+
|
56
|
+
def left_match
|
57
|
+
lefts.find { |pattern, _| either.left.select(&pattern).some? }.last
|
58
|
+
end
|
59
|
+
|
60
|
+
def right_match
|
61
|
+
rights.find { |pattern, _| either.right.select(&pattern).some? }.last
|
62
|
+
end
|
63
|
+
|
64
|
+
def lefts
|
65
|
+
match.lefts
|
66
|
+
end
|
67
|
+
|
68
|
+
def rights
|
69
|
+
match.rights
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/left.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Left
|
2
|
+
include Either
|
3
|
+
|
4
|
+
def self.[] value
|
5
|
+
new value
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(value)
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def left
|
13
|
+
Some[value]
|
14
|
+
end
|
15
|
+
|
16
|
+
def right
|
17
|
+
None
|
18
|
+
end
|
19
|
+
|
20
|
+
def left?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def right?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :value
|
31
|
+
end
|
data/lib/right.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class Right
|
2
|
+
include Either
|
3
|
+
|
4
|
+
def self.[] value
|
5
|
+
new value
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(value)
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def left
|
13
|
+
None
|
14
|
+
end
|
15
|
+
|
16
|
+
def right
|
17
|
+
Some[value]
|
18
|
+
end
|
19
|
+
|
20
|
+
def left?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def right?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :value
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Either
|
4
|
+
describe Match do
|
5
|
+
|
6
|
+
let (:match) { Match.new }
|
7
|
+
|
8
|
+
it 'can have a left match added to it' do
|
9
|
+
match.left { |x| x * 2 }
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'can have a right match added to it' do
|
13
|
+
match.right { |x| x * 4 }
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'evaluates the first match on the correct side that matches' do
|
17
|
+
match.left(5) { |x| x * x }
|
18
|
+
expect(match.evaluate(Left[5])).to eq 25
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Either do
|
4
|
+
|
5
|
+
it 'can have a left part' do
|
6
|
+
either = Left[:cats]
|
7
|
+
either.left.value.should eq :cats
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'can have a right part' do
|
11
|
+
either = Right[:cats]
|
12
|
+
either.right.value.should eq :cats
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Left do
|
4
|
+
|
5
|
+
subject { Left[:foo] }
|
6
|
+
|
7
|
+
it { should be_left }
|
8
|
+
it { should_not be_right }
|
9
|
+
|
10
|
+
it 'has a value on the left hand side' do
|
11
|
+
expect(subject.left.value).to eq :foo
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'does not have a value on the right hand side' do
|
15
|
+
expect { subject.right.value }.to raise_error Option::ValueOfNoneError
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can be pattern matched against' do
|
19
|
+
expect(
|
20
|
+
subject.match do |m|
|
21
|
+
m.left { |v| "It is a left: #{v}" }
|
22
|
+
m.right { |v| "It is not a left: #{v}" }
|
23
|
+
end
|
24
|
+
).to eq "It is a left: foo"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Right do
|
4
|
+
|
5
|
+
subject { Right[:foo] }
|
6
|
+
|
7
|
+
it { should_not be_left }
|
8
|
+
it { should be_right }
|
9
|
+
|
10
|
+
it 'has a value on the right hand side' do
|
11
|
+
expect(subject.right.value).to eq :foo
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'does not have a value on the left hand side' do
|
15
|
+
expect { subject.left.value }.to raise_error Option::ValueOfNoneError
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can be pattern matched against' do
|
19
|
+
expect(
|
20
|
+
subject.match do |m|
|
21
|
+
m.left { |v| "It is a left: #{v}" }
|
22
|
+
m.right { |v| "It is not a left: #{v}" }
|
23
|
+
end
|
24
|
+
).to eq "It is not a left: foo"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: either
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,6 +11,22 @@ bindir: bin
|
|
11
11
|
cert_chain: []
|
12
12
|
date: 2013-07-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: optional
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: rake
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,13 +83,24 @@ extensions: []
|
|
67
83
|
extra_rdoc_files: []
|
68
84
|
files:
|
69
85
|
- .gitignore
|
86
|
+
- .travis.yml
|
70
87
|
- Gemfile
|
71
88
|
- Gemfile.lock
|
72
89
|
- LICENSE.md
|
90
|
+
- README.md
|
73
91
|
- either.gemspec
|
92
|
+
- lib/either.rb
|
93
|
+
- lib/either/match.rb
|
94
|
+
- lib/left.rb
|
95
|
+
- lib/right.rb
|
96
|
+
- spec/lib/either/match_spec.rb
|
97
|
+
- spec/lib/either_spec.rb
|
98
|
+
- spec/lib/left_spec.rb
|
99
|
+
- spec/lib/right_spec.rb
|
74
100
|
- spec/spec_helper.rb
|
75
101
|
homepage: http://github.com/rsslldnphy/either
|
76
|
-
licenses:
|
102
|
+
licenses:
|
103
|
+
- MIT
|
77
104
|
post_install_message:
|
78
105
|
rdoc_options: []
|
79
106
|
require_paths:
|
@@ -92,10 +119,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
119
|
version: '0'
|
93
120
|
requirements: []
|
94
121
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.8.
|
122
|
+
rubygems_version: 1.8.23
|
96
123
|
signing_key:
|
97
124
|
specification_version: 3
|
98
125
|
summary: Either types with pattern matching
|
99
126
|
test_files:
|
127
|
+
- spec/lib/either/match_spec.rb
|
128
|
+
- spec/lib/either_spec.rb
|
129
|
+
- spec/lib/left_spec.rb
|
130
|
+
- spec/lib/right_spec.rb
|
100
131
|
- spec/spec_helper.rb
|
101
|
-
has_rdoc:
|