either 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - 1.8.7
6
+ - rbx-19mode
@@ -2,12 +2,14 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  either (0.0.1)
5
+ optional
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
10
  diff-lcs (1.2.4)
10
11
  multi_json (1.7.7)
12
+ optional (0.0.6)
11
13
  rake (10.1.0)
12
14
  rspec (2.13.0)
13
15
  rspec-core (~> 2.13.0)
@@ -0,0 +1,2 @@
1
+ [![Build Status](https://travis-ci.org/rsslldnphy/either.png)](https://travis-ci.org/rsslldnphy/either)
2
+ [![Code Climate](https://codeclimate.com/github/rsslldnphy/either.png)](https://codeclimate.com/github/rsslldnphy/either)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'either'
3
- s.version = '0.0.1'
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"
@@ -0,0 +1,10 @@
1
+ module Either
2
+ def match &block
3
+ Match.new.tap { |m| block.call(m) }.evaluate(self)
4
+ end
5
+ end
6
+
7
+ require 'optional'
8
+ require 'left'
9
+ require 'right'
10
+ require 'either/match'
@@ -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
@@ -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
@@ -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.1
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.25
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: