failure 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 222591a7509d0202f6c98d6ec6ed2158bbf225c8013f0b63bb325052233ee521
4
+ data.tar.gz: 987d4f4c9999e723d40af1ddf18ec5b518df1f23206e91e8d36aa58970076da4
5
+ SHA512:
6
+ metadata.gz: c831346698f2c59a15a5b919a845c8873693f5db793f576c27c43161ebaf386c99e7a1897c9ad7fb340b789986d828e6e3262c85627db26ebde31eb6f4e910f6
7
+ data.tar.gz: bce4d0ddd8cb24d7ba242baf513825569d6491abe18062eee64ac0a664c9459e8c99e60d3afff7d0f565ec2a6a2c2f1a18e88de3436712b4f9cc7e1288d6ff5c
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ Gemfile.lock
46
+ .ruby-version
47
+ .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ ruby '2.5.0'
4
+
5
+ # Specify your gem's dependencies in necklace.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # Failure is always an option
2
+
3
+ This library implements ruby-ified `Maybe` and `Either` types. Both capture
4
+ `nil` and `Exception` and return an object that implements the functor and monad
5
+ interfaces.
6
+
7
+ ## Usage
8
+
9
+ ### Maybe
10
+
11
+ `Maybe.new` takes a block and returns `Just <value>` on success and `Nothing` if
12
+ the block either returns `nil` or raises an exception.
13
+
14
+ ```ruby
15
+ Maybe.new do
16
+ [1, 2, 3].first
17
+ end
18
+
19
+ #=> Just 1
20
+
21
+ Maybe.new do
22
+ [].first
23
+ end
24
+
25
+ #=> Nothing
26
+ ```
27
+
28
+ `#map` is implemented on `Just` and `Nothing`, and is the functor `fmap`:
29
+
30
+ ```haskell
31
+ map :: Maybe a -> (a -> b) -> Maybe b
32
+ ```
33
+
34
+ ```ruby
35
+ Maybe.new do
36
+ [1, 2, 3].first
37
+ end.map do |i|
38
+ i * 100
39
+ end
40
+
41
+ #=> Just 100
42
+
43
+ Maybe.new do
44
+ [].first
45
+ end.map do |i|
46
+ i * 100
47
+ end
48
+
49
+ #=> Nothing
50
+ ```
51
+
52
+ `#flat_map` is implemented on `Just` and `Nothing`, and is the monad `bind`:
53
+
54
+ ```haskell
55
+ flat_map :: Maybe a -> (a -> Maybe b) -> Maybe b
56
+ ```
57
+
58
+ ```ruby
59
+ Maybe.new do
60
+ [[1], [2], [3]].first
61
+ end.flat_map do |i|
62
+ Maybe.new { i.first }
63
+ end
64
+
65
+ #=> Just 1
66
+
67
+ Maybe.new do
68
+ [1, 2, 3].first
69
+ end.flat_map do |i|
70
+ Maybe.new { i.first } # raises NoMethodError
71
+ end
72
+
73
+ #=> Nothing
74
+ ```
75
+
76
+ `Maybe.match` takes the maybe, a proc for the `Just` and a proc of no arguments
77
+ for the `Nothing` and returns the value of the associated variant. Because there
78
+ is no value for `Nothing`, a default value may be provided instead of a proc.
79
+
80
+
81
+ ```haskell
82
+ match :: Maybe a -> (a -> b) -> b -> b
83
+ ```
84
+
85
+ ```ruby
86
+ just = Maybe.new do
87
+ [1, 2, 3].first
88
+ end
89
+
90
+ nothing = Maybe.new do
91
+ [].first
92
+ end
93
+
94
+ Maybe.match(just,
95
+ just: ->(i) { i + 1 },
96
+ nothing: 0
97
+ )
98
+
99
+ #=> 2
100
+
101
+ Maybe.match(nothing,
102
+ just: ->(i) { i + 1 },
103
+ nothing: 0
104
+ )
105
+
106
+ #=> 0
107
+ ```
108
+
109
+ ### Either
110
+
111
+ `Either` is similar to `Maybe` except that it preserves an error message from a
112
+ captured exception, or (trivially) the `nil` returned from a failed function.
113
+
114
+ `Either.new` takes a block and returns `Right <value>` if the block "succeeds",
115
+ and `Left <err | nil>` if the block raises or returns `nil`.
116
+
117
+ ```ruby
118
+ Either.new do
119
+ [1, 2, 3].first
120
+ end
121
+
122
+ #=> Right 1
123
+
124
+ Either.new do
125
+ 1.first
126
+ end
127
+
128
+ #=> Left NoMethodError
129
+ ```
130
+
131
+ `#map` is implemented on `Right` and `Left` and is the functor `fmap`
132
+
133
+ ```haskell
134
+ map :: Either a b -> (b -> c) -> Either a c
135
+ ```
136
+
137
+ ```ruby
138
+ Either.new do
139
+ [1, 2, 3].first
140
+ end.map do |i|
141
+ i * 100
142
+ end
143
+
144
+ #=> Right 100
145
+
146
+ Either.new do
147
+ 1.first
148
+ end.map do |i|
149
+ i * 100
150
+ end
151
+
152
+ #=> Left NoMethodError
153
+ ```
154
+
155
+ `#flat_map` is implemented on `Right` and `Left` and is the monad `bind`
156
+
157
+ ```haskell
158
+ flat_map :: Either a b -> (b -> Either a c) -> Either a c
159
+ ```
160
+
161
+ ```ruby
162
+ Either.new do
163
+ [[1], [2], [3]].first
164
+ end.flat_map do |i|
165
+ Either.new { i.first }
166
+ end
167
+
168
+ #=> Right 1
169
+
170
+ Either.new do
171
+ [1, 2, 3].first
172
+ end.flat_map do |i|
173
+ Either.new { i.first }
174
+ end
175
+
176
+ #=> Left NoMethodError
177
+ ```
178
+
179
+ `Either.match` takes an either, a proc for `Right` and a proc for `Left`,
180
+ evaluates the proc corresponding to the variant, and returns the result.
181
+
182
+ ```haskell
183
+ match :: Either a b -> (a -> c) (b -> c) -> c
184
+ ```
185
+
186
+ ```ruby
187
+ right = Either.new do
188
+ [1, 2, 3].first
189
+ end
190
+
191
+ left = Either.new do
192
+ 1.first
193
+ end
194
+
195
+ Either.match(right,
196
+ right: ->(i) { i * 100 },
197
+ left: ->(e) { e.message }
198
+ )
199
+
200
+ #=> 100
201
+
202
+ Either.match(left,
203
+ right: ->(i) { i * 100 },
204
+ left: ->(e) { e.message }
205
+ )
206
+
207
+ #=> "NoMethodError (undefined method `first' for 1:Integer)"
208
+ ```
209
+
210
+ ## Type Safety
211
+
212
+ There isn't any. Users are free to reach inside the classes using
213
+ `instance_variable_get` or `send`, and users can use `flat_map` with a block
214
+ that doesn't return an either to "unwrap" the value. And nothing constrains the
215
+ two procs in `.match` to return the same type. If we wanted type safety, we'd
216
+ use Haskell or Rust. But, just like everything else in ruby, this can be used to
217
+ make programming nicer.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ desc 'Default: run specs.'
6
+ task :default => :spec
7
+
8
+ desc 'Run specs'
9
+ RSpec::Core::RakeTask.new(:spec)
10
+
11
+ desc 'Generate code coverage'
12
+ RSpec::Core::RakeTask.new(:coverage)
data/failure.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'failure'
3
+ s.version = '0.1.0'
4
+ s.date = '2018-04-18'
5
+ s.summary = "Either and Option functor/applicative/monad"
6
+ s.description = "Implements Either and Option a la Haskell"
7
+ s.authors = ["Stuart Terrett"]
8
+ s.email = 'shterrett@gmail.com'
9
+ s.files = ["lib/failure.rb"]
10
+ s.homepage = 'http://github.com/shterrett/failure'
11
+ s.license = 'MIT'
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16
+ s.require_paths = ['lib']
17
+
18
+ s.add_development_dependency("rspec", "~> 3.7")
19
+ s.add_development_dependency("rake", "~> 12.3")
20
+ s.add_development_dependency("simplecov", "~> 0.16")
21
+ s.add_development_dependency("pry", "~> 0.11")
22
+ end
data/lib/either.rb ADDED
@@ -0,0 +1,76 @@
1
+ require_relative "./shared"
2
+
3
+ module Either
4
+ def self.new(&block)
5
+ val = begin
6
+ block.call()
7
+ rescue Exception => e
8
+ e
9
+ end
10
+ if val.nil? || val.is_a?(Exception)
11
+ Left.new(val)
12
+ else
13
+ Right.new(val)
14
+ end
15
+ end
16
+
17
+ def self.match(e, left:, right:)
18
+ if e.right?
19
+ right.call(e.send(:val))
20
+ elsif e.left?
21
+ left.call(e.send(:val))
22
+ end
23
+ end
24
+
25
+ class Left
26
+ include Shared
27
+
28
+ def left?
29
+ true
30
+ end
31
+ def right?
32
+ false
33
+ end
34
+
35
+ def initialize(val)
36
+ @val = val
37
+ end
38
+
39
+ def map(&block)
40
+ self
41
+ end
42
+
43
+ def flat_map(&block)
44
+ self
45
+ end
46
+
47
+ private
48
+ attr_reader :val
49
+ end
50
+
51
+ class Right
52
+ include Shared
53
+
54
+ def left?
55
+ false
56
+ end
57
+ def right?
58
+ true
59
+ end
60
+
61
+ def initialize(val)
62
+ @val = val
63
+ end
64
+
65
+ def map
66
+ Either.new { yield val }
67
+ end
68
+
69
+ def flat_map
70
+ yield val
71
+ end
72
+
73
+ private
74
+ attr_reader :val
75
+ end
76
+ end
data/lib/failure.rb ADDED
@@ -0,0 +1,2 @@
1
+ require_relative "./either"
2
+ require_relative "./maybe"
data/lib/maybe.rb ADDED
@@ -0,0 +1,79 @@
1
+ require_relative "./shared"
2
+
3
+ module Maybe
4
+ def self.new(&block)
5
+ val = begin
6
+ block.call()
7
+ rescue Exception => e
8
+ e
9
+ end
10
+ if val.nil? || val.is_a?(Exception)
11
+ Nothing.new
12
+ else
13
+ Just.new val
14
+ end
15
+ end
16
+
17
+ def self.match(m, just:, nothing:)
18
+ if m.is_just?
19
+ just.call(m.send(:val))
20
+ elsif m.is_nothing?
21
+ if nothing.is_a? Proc
22
+ nothing.call
23
+ else
24
+ nothing
25
+ end
26
+ end
27
+ end
28
+
29
+ class Just
30
+ include Shared
31
+
32
+ def is_just?
33
+ true
34
+ end
35
+ def is_nothing?
36
+ false
37
+ end
38
+
39
+ def initialize(val)
40
+ @val = val
41
+ end
42
+
43
+ def map
44
+ Maybe.new { yield val }
45
+ end
46
+
47
+ def flat_map
48
+ yield val
49
+ end
50
+
51
+ private
52
+ attr_reader :val
53
+ end
54
+
55
+ class Nothing
56
+ include Shared
57
+
58
+ def is_just?
59
+ false
60
+ end
61
+ def is_nothing?
62
+ true
63
+ end
64
+
65
+ def map(&block)
66
+ self
67
+ end
68
+
69
+ def flat_map(&block)
70
+ self
71
+ end
72
+
73
+ private
74
+
75
+ def val
76
+ nil
77
+ end
78
+ end
79
+ end
data/lib/shared.rb ADDED
@@ -0,0 +1,10 @@
1
+ module Shared
2
+ def ==(other)
3
+ self.class == other.class &&
4
+ other.val_eq?(val)
5
+ end
6
+
7
+ def val_eq?(other_val)
8
+ other_val == val
9
+ end
10
+ end
@@ -0,0 +1,131 @@
1
+ require "spec_helper"
2
+
3
+ describe Either do
4
+ describe "new" do
5
+ it "returns a Right when given a non-nil value" do
6
+ e = Either.new do
7
+ 5
8
+ end
9
+
10
+ expect(e.left?).to be_falsey
11
+ expect(e.right?).to be_truthy
12
+ expect(e).to be_an_instance_of Either::Right
13
+ end
14
+
15
+ it "returns a Left when given a nil value" do
16
+ e = Either.new do
17
+ nil
18
+ end
19
+
20
+ expect(e.left?).to be_truthy
21
+ expect(e.right?).to be_falsey
22
+ expect(e).to be_an_instance_of Either::Left
23
+ end
24
+
25
+ it "returns a Left wrapping a returned exception" do
26
+ e = Either.new do
27
+ 1 / 0
28
+ end
29
+
30
+ expect(e.left?).to be_truthy
31
+ expect(e.right?).to be_falsey
32
+ expect(e).to be_an_instance_of Either::Left
33
+ end
34
+ end
35
+
36
+ describe "==" do
37
+ it "is false if one side is Left and the other is Right" do
38
+ r = Either.new { 5 }
39
+ l = Either.new { nil }
40
+ fake = Either::Right.new(nil)
41
+
42
+ expect(r == l).to be_falsey
43
+ expect(l == r).to be_falsey
44
+ expect(r == fake).to be_falsey
45
+ end
46
+
47
+ it "delegates to the value equality when comparing the same variant" do
48
+ r_1 = Either.new { 5 }
49
+ r_2 = Either.new { 6 }
50
+ r_3 = Either.new { 5 }
51
+
52
+ expect(r_1).not_to eq r_2
53
+ expect(r_1).to eq r_3
54
+
55
+ l_1 = Either.new { nil }
56
+ l_2 = Either.new { 1 / 0 }
57
+ l_3 = Either.new { nil }
58
+
59
+ expect(l_1).not_to eq l_2
60
+ expect(l_1).to eq l_3
61
+ end
62
+ end
63
+
64
+ describe "match" do
65
+ it "runs the function given for Right and returns the result if the variant is a Right" do
66
+ e = Either::Right.new(5)
67
+ result = Either.match(
68
+ e,
69
+ left: ->(v){ v + 5 },
70
+ right: ->(v){ v * 5 }
71
+ )
72
+
73
+ expect(result).to eq 25
74
+ end
75
+
76
+ it "runs the function given for Left and returns the result if the variant is a Left" do
77
+ e = Either::Left.new(5)
78
+ result = Either.match(
79
+ e,
80
+ left: ->(v){ v + 5 },
81
+ right: ->(v){ v * 5 }
82
+ )
83
+
84
+ expect(result).to eq 10
85
+ end
86
+ end
87
+ end
88
+
89
+ describe Either::Left do
90
+ describe "map" do
91
+ it "returns itself, ignoring the function" do
92
+ l = Either::Left.new(nil).map do |v|
93
+ v * 5
94
+ end
95
+
96
+ expect(l).to eq Either::Left.new(nil)
97
+ end
98
+ end
99
+
100
+ describe "flat_map" do
101
+ it "returns itself, ignoring the function" do
102
+ l = Either::Left.new(nil).map do |v|
103
+ Either.new { v / 0 }
104
+ end
105
+
106
+ expect(l).to eq Either::Left.new(nil)
107
+ end
108
+ end
109
+ end
110
+
111
+ describe Either::Right do
112
+ describe "map" do
113
+ it "applies the function to the wrapped value and returns the wrapped result" do
114
+ r = Either::Right.new(5).map do |v|
115
+ v + 5
116
+ end
117
+
118
+ expect(r).to eq Either::Right.new(10)
119
+ end
120
+ end
121
+
122
+ describe "flat_map" do
123
+ it "applies the function to the wrapped value and returns the resulting Either" do
124
+ r = Either::Right.new(5).flat_map do |v|
125
+ Either.new { v / 0 }
126
+ end
127
+
128
+ expect(r.left?).to be_truthy
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,135 @@
1
+ require "spec_helper"
2
+
3
+ describe Maybe do
4
+ describe "new" do
5
+ it "returns a Just when given a non-nil value" do
6
+ m = Maybe.new do
7
+ 5
8
+ end
9
+
10
+ expect(m.is_just?).to be_truthy
11
+ expect(m.is_nothing?).to be_falsey
12
+ expect(m).to be_an_instance_of Maybe::Just
13
+ end
14
+
15
+ it "returns a Nothing when given a nil value"do
16
+ m = Maybe.new do
17
+ nil
18
+ end
19
+
20
+ expect(m.is_just?).to be_falsey
21
+ expect(m.is_nothing?).to be_truthy
22
+ expect(m).to be_an_instance_of Maybe::Nothing
23
+ end
24
+
25
+ it "returns a Nothing if the expression throws an exception" do
26
+ m = Maybe.new do
27
+ 1 / 0
28
+ end
29
+
30
+ expect(m.is_just?).to be_falsey
31
+ expect(m.is_nothing?).to be_truthy
32
+ expect(m).to be_an_instance_of Maybe::Nothing
33
+ end
34
+ end
35
+
36
+ describe "==" do
37
+ it "is false if one side is Just and the other is Nothing" do
38
+ j = Maybe.new { 5 }
39
+ n = Maybe.new { nil }
40
+ fake = Maybe::Just.new(nil)
41
+
42
+ expect(j == n).to be_falsey
43
+ expect(n == j).to be_falsey
44
+ expect(j == fake).to be_falsey
45
+ end
46
+
47
+ it "delegates to the value when comparing Just values" do
48
+ j_1 = Maybe.new { 5 }
49
+ j_2 = Maybe.new { 6 }
50
+ j_3 = Maybe.new { 5 }
51
+
52
+ expect(j_1).not_to eq j_2
53
+ expect(j_1).to eq j_3
54
+ end
55
+ end
56
+
57
+ describe "match" do
58
+ it "runs the function given for Just and returns the result if the variant is Just" do
59
+ m = Maybe::Just.new(5)
60
+ result = Maybe.match(
61
+ m,
62
+ just: ->(v) { v + 5 },
63
+ nothing: -> { 0 }
64
+ )
65
+
66
+ expect(result).to eq 10
67
+ end
68
+
69
+ it "runs the function given for Nothing and returns the result if the variant is Nothing" do
70
+ m = Maybe::Nothing.new
71
+ result = Maybe.match(
72
+ m,
73
+ just: ->(v) { v + 5 },
74
+ nothing: -> { 0 }
75
+ )
76
+
77
+ expect(result).to eq 0
78
+ end
79
+
80
+ it "returns the static default given for Nothing if the variant is Nothing" do
81
+ m = Maybe::Nothing.new
82
+ result = Maybe.match(
83
+ m,
84
+ just: ->(v) { v + 5 },
85
+ nothing: 0
86
+ )
87
+
88
+ expect(result).to eq 0
89
+ end
90
+ end
91
+ end
92
+
93
+ describe Maybe::Nothing do
94
+ describe "map" do
95
+ it "returns itself, ignoring the function" do
96
+ n = Maybe::Nothing.new.map do |v|
97
+ v * 5
98
+ end
99
+
100
+ expect(n).to eq Maybe::Nothing.new
101
+ end
102
+ end
103
+
104
+ describe "flat_map" do
105
+ it "returns itself, ignoring the function" do
106
+ n = Maybe::Nothing.new.flat_map do |v|
107
+ Maybe.new { v * 5 }
108
+ end
109
+
110
+ expect(n).to eq Maybe::Nothing.new
111
+ end
112
+ end
113
+ end
114
+
115
+ describe Maybe::Just do
116
+ describe "map" do
117
+ it "applies the function to the wrapped value and returns the wrapped result" do
118
+ j = Maybe::Just.new(5).map do |v|
119
+ v * 5
120
+ end
121
+
122
+ expect(j).to eq Maybe::Just.new(25)
123
+ end
124
+ end
125
+
126
+ describe "flat_map" do
127
+ it "applies the function to the wrapped value and returns the resulting Maybe" do
128
+ m = Maybe::Just.new(5).flat_map do |v|
129
+ Maybe.new { v / 0 }
130
+ end
131
+
132
+ expect(m.is_nothing?).to be_truthy
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,19 @@
1
+ require 'simplecov'
2
+ require "pry"
3
+
4
+ SimpleCov.start do
5
+ add_filter 'spec/'
6
+ end
7
+
8
+ # encoding: utf-8
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+
12
+ Dir['./spec/shared/**/*.rb'].sort.each { |f| require f }
13
+ require_relative '../lib/failure'
14
+
15
+ require 'rspec'
16
+
17
+ RSpec.configure do |config|
18
+ config.order = 'random'
19
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: failure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Stuart Terrett
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-04-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.16'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.11'
69
+ description: Implements Either and Option a la Haskell
70
+ email: shterrett@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - Gemfile
77
+ - README.md
78
+ - Rakefile
79
+ - failure.gemspec
80
+ - lib/either.rb
81
+ - lib/failure.rb
82
+ - lib/maybe.rb
83
+ - lib/shared.rb
84
+ - spec/either_spec.rb
85
+ - spec/maybe_spec.rb
86
+ - spec/spec_helper.rb
87
+ homepage: http://github.com/shterrett/failure
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.7.3
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Either and Option functor/applicative/monad
111
+ test_files:
112
+ - spec/either_spec.rb
113
+ - spec/maybe_spec.rb
114
+ - spec/spec_helper.rb