easy_monads 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "pry"
10
+ gem "shoulda", "~> 2.11.3"
11
+ gem "shared_should", "~> 0.8.1"
12
+ gem "always_execute", "~> 0.0.2"
13
+ gem "bundler", "~> 1.0.21"
14
+ gem "jeweler", "~> 1.6.4"
15
+ gem "rcov", "~> 0.9.11"
16
+ gem "rdoc", ">= 2.4.2"
17
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Stephen Sloan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "easy_monads"
18
+ gem.homepage = "https://github.com/bkr/easy_monads"
19
+ gem.license = "MIT"
20
+ gem.summary = "EasyMonads is a simple implementation of monads for Ruby"
21
+ gem.description = <<EOS
22
+ EasyMonads is a gem for Ruby that provides a simple implementation of monads. It also provides a useful example of
23
+ monads in the form of Option (similar to Scala's Option) which provides Some and None classes.
24
+
25
+ Developement for EasyMonads is sponsored by BookRenter.com and it is released under an MIT-style license
26
+ EOS
27
+ gem.email = "stephen.sloan@bookrenter.com"
28
+ gem.authors = ["Stephen Sloan"]
29
+ # dependencies defined in Gemfile
30
+ end
31
+ Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.libs << 'lib' << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = true
45
+ test.rcov_opts << '--exclude "gems/*"'
46
+ end
47
+
48
+ task :default => :test
49
+
50
+ require 'rdoc/task'
51
+ Rake::RDocTask.new do |rdoc|
52
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
53
+
54
+ rdoc.rdoc_dir = 'rdoc'
55
+ rdoc.title = "easy_monads #{version}"
56
+ rdoc.rdoc_files.include('README*')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,73 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "easy_monads"
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Stephen Sloan"]
12
+ s.date = "2011-12-06"
13
+ s.description = "EasyMonads is a gem for Ruby that provides a simple implementation of monads. It also provides a useful example of\nmonads in the form of Option (similar to Scala's Option) which provides Some and None classes.\n\nDevelopement for EasyMonads is sponsored by BookRenter.com and it is released under an MIT-style license\n"
14
+ s.email = "stephen.sloan@bookrenter.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "easy_monads.gemspec",
27
+ "lib/easy_monads.rb",
28
+ "lib/easy_monads/monadic.rb",
29
+ "lib/easy_monads/option.rb",
30
+ "lib/easy_monads/option_functions.rb",
31
+ "test/helper.rb",
32
+ "test/test_easy_monads.rb"
33
+ ]
34
+ s.homepage = "https://github.com/bkr/easy_monads"
35
+ s.licenses = ["MIT"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = "1.8.10"
38
+ s.summary = "EasyMonads is a simple implementation of monads for Ruby"
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_development_dependency(%q<pry>, [">= 0"])
45
+ s.add_development_dependency(%q<shoulda>, ["~> 2.11.3"])
46
+ s.add_development_dependency(%q<shared_should>, ["~> 0.8.1"])
47
+ s.add_development_dependency(%q<always_execute>, ["~> 0.0.2"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.21"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
50
+ s.add_development_dependency(%q<rcov>, ["~> 0.9.11"])
51
+ s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
52
+ else
53
+ s.add_dependency(%q<pry>, [">= 0"])
54
+ s.add_dependency(%q<shoulda>, ["~> 2.11.3"])
55
+ s.add_dependency(%q<shared_should>, ["~> 0.8.1"])
56
+ s.add_dependency(%q<always_execute>, ["~> 0.0.2"])
57
+ s.add_dependency(%q<bundler>, ["~> 1.0.21"])
58
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
59
+ s.add_dependency(%q<rcov>, ["~> 0.9.11"])
60
+ s.add_dependency(%q<rdoc>, [">= 2.4.2"])
61
+ end
62
+ else
63
+ s.add_dependency(%q<pry>, [">= 0"])
64
+ s.add_dependency(%q<shoulda>, ["~> 2.11.3"])
65
+ s.add_dependency(%q<shared_should>, ["~> 0.8.1"])
66
+ s.add_dependency(%q<always_execute>, ["~> 0.0.2"])
67
+ s.add_dependency(%q<bundler>, ["~> 1.0.21"])
68
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
69
+ s.add_dependency(%q<rcov>, ["~> 0.9.11"])
70
+ s.add_dependency(%q<rdoc>, [">= 2.4.2"])
71
+ end
72
+ end
73
+
@@ -0,0 +1,44 @@
1
+ module EasyMonads
2
+ class Monadic
3
+ include Enumerable
4
+ include Comparable
5
+
6
+ class << self
7
+ def unit(*args)
8
+ new(*args)
9
+ end
10
+ end
11
+
12
+ def unit(to_wrap)
13
+ self.class.unit(to_wrap)
14
+ end
15
+
16
+ def bind(&func)
17
+ result = func.call(data) if defined? @data
18
+ raise RuntimeError.new("Result of .bind must be a Monadic but was #{result.class.name}") unless result.is_a? Monadic
19
+ result
20
+ end
21
+
22
+ def bind_unit(&func)
23
+ self.bind { |*args| self.unit(func.call(*args)) }
24
+ end
25
+
26
+ def data
27
+ @data
28
+ end
29
+
30
+ def each
31
+ yield data
32
+ end
33
+
34
+ def ==(other_monad)
35
+ return false unless other_monad.is_a? EasyMonads::Monadic
36
+ data == other_monad.data
37
+ end
38
+
39
+ def <=>(other_monad)
40
+ return RuntimeError.new("Can only compare with other Monadic objects") unless other_monad.is_a? EasyMonads::Monadic
41
+ data <=> other_monad.data
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,98 @@
1
+
2
+ module EasyMonads
3
+ module Option
4
+ class Option < EasyMonads::Monadic
5
+ def initialize(*args)
6
+ raise RuntimeError.new("Attempt to initialize abstract #{self.class.name} class")
7
+ end
8
+
9
+ alias get data
10
+ alias or_nil data
11
+ end
12
+
13
+ class None < Option
14
+ def initialize(*args)
15
+ @data = nil
16
+ end
17
+
18
+ def bind
19
+ self
20
+ end
21
+
22
+ def each
23
+ end
24
+
25
+ def ==(other_monad)
26
+ other_monad.is_a? self.class
27
+ end
28
+
29
+ def <=>(other_monad)
30
+ if self == other_monad
31
+ 0
32
+ else
33
+ raise RuntimeError.new("#{self.class.name} is not comparable to other types") # nil <=> ... would raise NoMethodError
34
+ end
35
+ end
36
+
37
+ def size
38
+ 0
39
+ end
40
+
41
+ def exists?(&pred)
42
+ false
43
+ end
44
+
45
+ def defined?
46
+ false
47
+ end
48
+
49
+ def get_or_else(else_val=nil)
50
+ if block_given?
51
+ yield
52
+ else
53
+ else_val
54
+ end
55
+ end
56
+
57
+ def empty?
58
+ true
59
+ end
60
+
61
+ def or_else
62
+ yield
63
+ end
64
+ end
65
+
66
+ NONE = None.new.freeze
67
+
68
+ class Some < Option
69
+ def initialize(data)
70
+ @data = data
71
+ end
72
+
73
+ def size
74
+ 1
75
+ end
76
+
77
+ def exists?(&pred)
78
+ pred.call(data) ? true : false
79
+ end
80
+
81
+ def defined?
82
+ true
83
+ end
84
+
85
+ def get_or_else(ignored=nil)
86
+ data
87
+ end
88
+
89
+ def empty?
90
+ false
91
+ end
92
+
93
+ def or_else
94
+ self
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,15 @@
1
+
2
+ module EasyMonads
3
+ module Option
4
+ module OptionFunctions
5
+ def self.sum_option_in_hash(hash, key, option)
6
+ if hash[key].is_a? Some
7
+ hash[key] = hash[key].bind { |value| Some.unit(value + option.get) }
8
+ else
9
+ hash[key] = option
10
+ end
11
+ hash
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), "easy_monads", "monadic")
2
+ require File.join(File.dirname(__FILE__), "easy_monads", "option")
3
+ require File.join(File.dirname(__FILE__), "easy_monads", "option_functions")
4
+
5
+ module EasyMonads
6
+
7
+ def self.option_everywhere!
8
+ Object.class_eval("include EasyMonads::Option")
9
+ end
10
+
11
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+ require 'shared_should'
13
+ require 'always_execute'
14
+
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+ require 'easy_monads'
18
+
19
+ class Test::Unit::TestCase
20
+ end
@@ -0,0 +1,196 @@
1
+ require 'helper'
2
+
3
+ class TestEasyMonads < Test::Unit::TestCase
4
+ # What the hell is a monad, you ask? Check out
5
+ # http://www.codecommit.com/blog/ruby/monads-are-not-metaphors
6
+
7
+ class TestMonadic < EasyMonads::Monadic
8
+ def initialize(data)
9
+ @data = data
10
+ end
11
+ end
12
+
13
+ context "A monadic Object" do
14
+ setup do
15
+ @monad = TestMonadic.new("test")
16
+ end
17
+
18
+ should "be enumerable" do
19
+ assert @monad.is_a? Enumerable
20
+ assert defined? @monad.each
21
+ end
22
+
23
+ should "be comparable" do
24
+ assert @monad.is_a? Comparable
25
+ assert defined? @monad.<=>
26
+ end
27
+
28
+ should "expose its contained data" do
29
+ assert_equal "test", @monad.data
30
+ end
31
+
32
+ should "have a fancy bind_unit method that does a bind and a unit in one" do
33
+ assert_equal TestMonadic.new("TEST"), @monad.bind_unit { |value| value.upcase }
34
+ end
35
+
36
+ # For all this monad identity business, checkout out
37
+ # http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/01identity
38
+ should "be true for identify law one" do
39
+ f = lambda { |value| TestMonadic.unit("#{value} foo") }
40
+ assert_equal "test foo", @monad.bind { |value| f.call(value) }.data
41
+ assert_equal f.call("test"), @monad.bind { |value| f.call(value) }
42
+ end
43
+
44
+ should "be true for identity law two" do
45
+ assert_equal @monad, @monad.bind { |value| TestMonadic.unit(value) }
46
+ end
47
+
48
+ context "for identity law three" do
49
+ setup do
50
+ @f = lambda { |value| TestMonadic.unit(value * 2) }
51
+ @g = lambda { |value| TestMonadic.unit("#{value} foo") }
52
+ end
53
+
54
+ execute do
55
+ @monad.bind do |value_a|
56
+ @f.call(value_a)
57
+ end.bind do |value_b|
58
+ @g.call(value_b)
59
+ end
60
+ end
61
+
62
+ should "be true" do
63
+ assert_equal "testtest foo", @execute_result.data
64
+ test_result = @monad.bind do |value_a|
65
+ @f.call(value_a).bind do |value_b|
66
+ @g.call(value_b)
67
+ end
68
+ end
69
+ assert_equal @execute_result, test_result
70
+ end
71
+ end
72
+ end
73
+
74
+ context "An Option" do
75
+
76
+ should "raise an error if used directly" do
77
+ assert_raises(RuntimeError) { EasyMonads::Option::Option.new("foo") }
78
+ end
79
+
80
+ context "that is a None" do
81
+ setup do
82
+ @none = EasyMonads::Option::NONE
83
+ end
84
+
85
+ should "not bind to anything" do
86
+ assert_equal EasyMonads::Option::NONE, @none.bind { raise RuntimeError.new("Should not have entered block") }
87
+ end
88
+
89
+ should "not enumerate" do
90
+ count = 0
91
+ @none.each { count += 1 }
92
+ assert_equal 0, count
93
+ end
94
+
95
+ should "return nil for .get" do
96
+ assert_equal nil, @none.get
97
+ end
98
+
99
+ should "return true for .empty?" do
100
+ assert_equal true, @none.empty?
101
+ end
102
+
103
+ should "return 0 for .size" do
104
+ assert_equal 0, @none.size
105
+ end
106
+
107
+ should "return false always for .exists? and not call the predicate block" do
108
+ assert_equal false, @none.exists? { raise RuntimeError.new("Should not enter the block") }
109
+ end
110
+
111
+ should "return the else for .get_or_else" do
112
+ assert_equal "foo", @none.get_or_else("foo")
113
+ end
114
+
115
+ should "return the evaluated block for .get_or_else when passed a block" do
116
+ assert_equal "foo", @none.get_or_else { "foo" }
117
+ end
118
+
119
+ should "return false for .defined?" do
120
+ assert_equal false, @none.defined?
121
+ end
122
+
123
+ should "return nil for .or_nil" do
124
+ assert_equal nil, @none.or_nil
125
+ end
126
+
127
+ should "execute the block for .or_else" do
128
+ entered = "grouchy"
129
+ @none.or_else { entered = "happy" }
130
+ assert_equal "happy", entered
131
+ end
132
+ end
133
+
134
+ context "that is a Some" do
135
+ setup do
136
+ @some = EasyMonads::Option::Some.new("hello")
137
+ end
138
+
139
+ should "bind to another Some" do
140
+ assert_equal "hello world", @some.bind { |value| EasyMonads::Option::Some.new("#{value} world") }.data
141
+ end
142
+
143
+ should "enumerate" do
144
+ count = 0
145
+ @some.each { count += 1 }
146
+ assert_equal 1, count
147
+ end
148
+
149
+ should "return its data for .get" do
150
+ assert_equal "hello", @some.get
151
+ end
152
+
153
+ should "return false for .empty?" do
154
+ assert_equal false, @some.empty?
155
+ end
156
+
157
+ should "return 1 for its size" do
158
+ assert_equal 1, @some.size
159
+ another_some = EasyMonads::Option::Some.new(["hello", "world"])
160
+ assert_equal 1, another_some.size
161
+ end
162
+
163
+ should "return true when a predicate is true for .exists?" do
164
+ assert_equal true, @some.exists? { |value| value == "hello" }
165
+ end
166
+
167
+ should "return false when a predicate is false for .exists?" do
168
+ assert_equal false, @some.exists? { |value| value == "fooie" }
169
+ end
170
+
171
+ should "return its data for .get_or_else" do
172
+ assert_equal "hello", @some.get_or_else("goodbye")
173
+ end
174
+
175
+ should "return its data and ignore the block for .get_or_else when passed a block" do
176
+ assert_equal "hello", @some.get_or_else { raise RuntimeError.new("Should not enter the block") }
177
+ end
178
+
179
+ should "return true for .defined?" do
180
+ assert_equal true, @some.defined?
181
+ end
182
+
183
+ should "return its data for .or_nil" do
184
+ assert_equal "hello", @some.or_nil
185
+ end
186
+
187
+ should "not enter the block for .or_else" do
188
+ assert_nothing_raised { @some.or_else { raise RuntimeError.new("Should not enter the block") } }
189
+ end
190
+
191
+ should "return self for .or_else" do
192
+ assert_equal @some, @some.or_else {}
193
+ end
194
+ end
195
+ end
196
+ end
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easy_monads
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Stephen Sloan
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-12-06 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ version_requirements: *id001
31
+ name: pry
32
+ prerelease: false
33
+ type: :development
34
+ - !ruby/object:Gem::Dependency
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ hash: 37
41
+ segments:
42
+ - 2
43
+ - 11
44
+ - 3
45
+ version: 2.11.3
46
+ version_requirements: *id002
47
+ name: shoulda
48
+ prerelease: false
49
+ type: :development
50
+ - !ruby/object:Gem::Dependency
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ hash: 61
57
+ segments:
58
+ - 0
59
+ - 8
60
+ - 1
61
+ version: 0.8.1
62
+ version_requirements: *id003
63
+ name: shared_should
64
+ prerelease: false
65
+ type: :development
66
+ - !ruby/object:Gem::Dependency
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ hash: 27
73
+ segments:
74
+ - 0
75
+ - 0
76
+ - 2
77
+ version: 0.0.2
78
+ version_requirements: *id004
79
+ name: always_execute
80
+ prerelease: false
81
+ type: :development
82
+ - !ruby/object:Gem::Dependency
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ hash: 61
89
+ segments:
90
+ - 1
91
+ - 0
92
+ - 21
93
+ version: 1.0.21
94
+ version_requirements: *id005
95
+ name: bundler
96
+ prerelease: false
97
+ type: :development
98
+ - !ruby/object:Gem::Dependency
99
+ requirement: &id006 !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ~>
103
+ - !ruby/object:Gem::Version
104
+ hash: 7
105
+ segments:
106
+ - 1
107
+ - 6
108
+ - 4
109
+ version: 1.6.4
110
+ version_requirements: *id006
111
+ name: jeweler
112
+ prerelease: false
113
+ type: :development
114
+ - !ruby/object:Gem::Dependency
115
+ requirement: &id007 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ hash: 45
121
+ segments:
122
+ - 0
123
+ - 9
124
+ - 11
125
+ version: 0.9.11
126
+ version_requirements: *id007
127
+ name: rcov
128
+ prerelease: false
129
+ type: :development
130
+ - !ruby/object:Gem::Dependency
131
+ requirement: &id008 !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 27
137
+ segments:
138
+ - 2
139
+ - 4
140
+ - 2
141
+ version: 2.4.2
142
+ version_requirements: *id008
143
+ name: rdoc
144
+ prerelease: false
145
+ type: :development
146
+ description: |
147
+ EasyMonads is a gem for Ruby that provides a simple implementation of monads. It also provides a useful example of
148
+ monads in the form of Option (similar to Scala's Option) which provides Some and None classes.
149
+
150
+ Developement for EasyMonads is sponsored by BookRenter.com and it is released under an MIT-style license
151
+
152
+ email: stephen.sloan@bookrenter.com
153
+ executables: []
154
+
155
+ extensions: []
156
+
157
+ extra_rdoc_files:
158
+ - LICENSE.txt
159
+ - README.md
160
+ files:
161
+ - .document
162
+ - Gemfile
163
+ - LICENSE.txt
164
+ - README.md
165
+ - Rakefile
166
+ - VERSION
167
+ - easy_monads.gemspec
168
+ - lib/easy_monads.rb
169
+ - lib/easy_monads/monadic.rb
170
+ - lib/easy_monads/option.rb
171
+ - lib/easy_monads/option_functions.rb
172
+ - test/helper.rb
173
+ - test/test_easy_monads.rb
174
+ homepage: https://github.com/bkr/easy_monads
175
+ licenses:
176
+ - MIT
177
+ post_install_message:
178
+ rdoc_options: []
179
+
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ none: false
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ hash: 3
188
+ segments:
189
+ - 0
190
+ version: "0"
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
192
+ none: false
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ hash: 3
197
+ segments:
198
+ - 0
199
+ version: "0"
200
+ requirements: []
201
+
202
+ rubyforge_project:
203
+ rubygems_version: 1.8.10
204
+ signing_key:
205
+ specification_version: 3
206
+ summary: EasyMonads is a simple implementation of monads for Ruby
207
+ test_files: []
208
+