failure 0.1.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 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