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.
@@ -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: