monad-maybe 0.9.8 → 0.9.9
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 +4 -4
- data/Gemfile +7 -7
- data/Gemfile.lock +24 -24
- data/README.md +12 -12
- data/Rakefile +25 -24
- data/VERSION +1 -1
- data/lib/monad/maybe.rb +59 -59
- data/lib/monad/maybe/base.rb +39 -39
- data/lib/monad/maybe/json.rb +26 -26
- data/lib/monad/maybe/just.rb +62 -62
- data/lib/monad/maybe/list.rb +72 -72
- data/lib/monad/maybe/nothing.rb +58 -58
- data/monad-maybe.gemspec +57 -56
- data/test/maybe.rb +158 -158
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4b9973bafaf3d9e728106f0ca22fcd9e1c6cc25
|
4
|
+
data.tar.gz: 30d80d184fe6500b0a428a00ebd1766cf59e7824
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a217e29d79862e5a2966c60ff653e12aafee6d6b96ac508b92f7eeec2cb6d617a5843f998f21b45966e9dee70d412ca0616591f7cc5eaf5ec028230e02797b2
|
7
|
+
data.tar.gz: 0976f7d7acb1d70d91a98034422d99fd00a6abb5159de54733e2cd1a5a58094c7721cd9f15114a464e7b7f66cbf7e2f92a98317c507d1564071a32b9b397a841
|
data/Gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
source "http://rubygems.org"
|
2
|
-
|
3
|
-
group :development do
|
4
|
-
gem 'jeweler'
|
5
|
-
gem 'yard'
|
6
|
-
gem 'test-unit'
|
7
|
-
end
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
group :development do
|
4
|
+
gem 'jeweler'
|
5
|
+
gem 'yard'
|
6
|
+
gem 'test-unit'
|
7
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
git (1.2.5)
|
5
|
-
jeweler (1.8.4)
|
6
|
-
bundler (~> 1.0)
|
7
|
-
git (>= 1.2.5)
|
8
|
-
rake
|
9
|
-
rdoc
|
10
|
-
json (1.8.0)
|
11
|
-
rake (10.0.4)
|
12
|
-
rdoc (4.0.1)
|
13
|
-
json (~> 1.4)
|
14
|
-
test-unit (2.5.5)
|
15
|
-
yard (0.8.6.1)
|
16
|
-
|
17
|
-
PLATFORMS
|
18
|
-
ruby
|
19
|
-
x86-mingw32
|
20
|
-
|
21
|
-
DEPENDENCIES
|
22
|
-
jeweler
|
23
|
-
test-unit
|
24
|
-
yard
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.8.4)
|
6
|
+
bundler (~> 1.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
rdoc
|
10
|
+
json (1.8.0)
|
11
|
+
rake (10.0.4)
|
12
|
+
rdoc (4.0.1)
|
13
|
+
json (~> 1.4)
|
14
|
+
test-unit (2.5.5)
|
15
|
+
yard (0.8.6.1)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
x86-mingw32
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
jeweler
|
23
|
+
test-unit
|
24
|
+
yard
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
`monad-maybe`
|
2
|
-
=============
|
3
|
-
|
4
|
-
An Implementation of Haskell's Maybe Mondad
|
5
|
-
-------------------------------------------
|
6
|
-
|
7
|
-
This is an attempt to implement Haskell's Maybe monad in a Ruby-ish way with as little monkey patching as possible.
|
8
|
-
|
9
|
-
SEE ALSO
|
10
|
-
========
|
11
|
-
[andand](http://)
|
12
|
-
[Haskell's Maybe Monad](http://)
|
1
|
+
`monad-maybe`
|
2
|
+
=============
|
3
|
+
|
4
|
+
An Implementation of Haskell's Maybe Mondad
|
5
|
+
-------------------------------------------
|
6
|
+
|
7
|
+
This is an attempt to implement Haskell's Maybe monad in a Ruby-ish way with as little monkey patching as possible.
|
8
|
+
|
9
|
+
SEE ALSO
|
10
|
+
========
|
11
|
+
[andand](http://)
|
12
|
+
[Haskell's Maybe Monad](http://)
|
data/Rakefile
CHANGED
@@ -1,24 +1,25 @@
|
|
1
|
-
require 'rake/testtask'
|
2
|
-
require 'jeweler'
|
3
|
-
Jeweler::Tasks.new do |gem|
|
4
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
5
|
-
gem.name = "monad-maybe"
|
6
|
-
gem.summary = %Q{A Ruby implementation of Haskell's Maybe Monad}
|
7
|
-
gem.description = %Q{This is an attempt to implement Haskell's Maybe monad in a Ruby-ish way.}
|
8
|
-
gem.email = "delon.newman@gmail.com"
|
9
|
-
gem.homepage = "https://github.com/delonnewman/monad-maybe"
|
10
|
-
gem.authors = ["Delon Newman"]
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
5
|
+
gem.name = "monad-maybe"
|
6
|
+
gem.summary = %Q{A Ruby implementation of Haskell's Maybe Monad}
|
7
|
+
gem.description = %Q{This is an attempt to implement Haskell's Maybe monad in a Ruby-ish way.}
|
8
|
+
gem.email = "delon.newman@gmail.com"
|
9
|
+
gem.homepage = "https://github.com/delonnewman/monad-maybe"
|
10
|
+
gem.authors = ["Delon Newman"]
|
11
|
+
gem.license = 'MIT'
|
12
|
+
end
|
13
|
+
Jeweler::RubygemsDotOrgTasks.new
|
14
|
+
|
15
|
+
desc "Run tests in ./test"
|
16
|
+
task :test do
|
17
|
+
Dir['test/*.rb'].each do |test|
|
18
|
+
sh "ruby #{test}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Setup for development"
|
23
|
+
task :setup do
|
24
|
+
sh "bundle"
|
25
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.9
|
data/lib/monad/maybe.rb
CHANGED
@@ -1,59 +1,59 @@
|
|
1
|
-
require_relative 'maybe/base'
|
2
|
-
require_relative 'maybe/just'
|
3
|
-
require_relative 'maybe/nothing'
|
4
|
-
require_relative 'maybe/list'
|
5
|
-
|
6
|
-
#
|
7
|
-
# Some monkey patching and constructor methods.
|
8
|
-
#
|
9
|
-
module Enumerable
|
10
|
-
def maybe_map
|
11
|
-
Monad::Maybe::List.new(map{ |x| yield(x) })
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class Object
|
16
|
-
def to_maybe(&blk)
|
17
|
-
j = Monad::Maybe::Just.new(self)
|
18
|
-
blk ? j.maybe(&blk) : j
|
19
|
-
end
|
20
|
-
|
21
|
-
def maybe?
|
22
|
-
false
|
23
|
-
end
|
24
|
-
|
25
|
-
def just?
|
26
|
-
false
|
27
|
-
end
|
28
|
-
|
29
|
-
def nothing?
|
30
|
-
false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class NilClass
|
35
|
-
def to_maybe(&blk)
|
36
|
-
Monad::Maybe::Nothing.instance
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
module Monad
|
41
|
-
module Maybe
|
42
|
-
def self.return(obj)
|
43
|
-
obj.to_maybe
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def maybe(obj, &blk)
|
49
|
-
m = Monad::Maybe.return(obj)
|
50
|
-
blk ? m.maybe(&blk) : m
|
51
|
-
end
|
52
|
-
|
53
|
-
def just(o)
|
54
|
-
Monad::Maybe::Just.new(o)
|
55
|
-
end
|
56
|
-
|
57
|
-
def nothing
|
58
|
-
Monad::Maybe::Nothing.instance
|
59
|
-
end
|
1
|
+
require_relative 'maybe/base'
|
2
|
+
require_relative 'maybe/just'
|
3
|
+
require_relative 'maybe/nothing'
|
4
|
+
require_relative 'maybe/list'
|
5
|
+
|
6
|
+
#
|
7
|
+
# Some monkey patching and constructor methods.
|
8
|
+
#
|
9
|
+
module Enumerable
|
10
|
+
def maybe_map
|
11
|
+
Monad::Maybe::List.new(map{ |x| yield(x) })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Object
|
16
|
+
def to_maybe(&blk)
|
17
|
+
j = Monad::Maybe::Just.new(self)
|
18
|
+
blk ? j.maybe(&blk) : j
|
19
|
+
end
|
20
|
+
|
21
|
+
def maybe?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
def just?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def nothing?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class NilClass
|
35
|
+
def to_maybe(&blk)
|
36
|
+
Monad::Maybe::Nothing.instance
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module Monad
|
41
|
+
module Maybe
|
42
|
+
def self.return(obj)
|
43
|
+
obj.to_maybe
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def maybe(obj, &blk)
|
49
|
+
m = Monad::Maybe.return(obj)
|
50
|
+
blk ? m.maybe(&blk) : m
|
51
|
+
end
|
52
|
+
|
53
|
+
def just(o)
|
54
|
+
Monad::Maybe::Just.new(o)
|
55
|
+
end
|
56
|
+
|
57
|
+
def nothing
|
58
|
+
Monad::Maybe::Nothing.instance
|
59
|
+
end
|
data/lib/monad/maybe/base.rb
CHANGED
@@ -1,39 +1,39 @@
|
|
1
|
-
module Monad
|
2
|
-
module Maybe
|
3
|
-
class Base
|
4
|
-
attr_reader :value
|
5
|
-
|
6
|
-
def <<(obj)
|
7
|
-
to_list << obj
|
8
|
-
end
|
9
|
-
|
10
|
-
def maybe?
|
11
|
-
true
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_list
|
15
|
-
List.new(to_a)
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_maybe
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
def maybe(&blk)
|
23
|
-
bind(blk)
|
24
|
-
end
|
25
|
-
|
26
|
-
def then(fn)
|
27
|
-
bind(->(x){ fn && fn.call })
|
28
|
-
self
|
29
|
-
end
|
30
|
-
|
31
|
-
def and(&blk)
|
32
|
-
self.then(blk)
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
def initialize; end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
1
|
+
module Monad
|
2
|
+
module Maybe
|
3
|
+
class Base
|
4
|
+
attr_reader :value
|
5
|
+
|
6
|
+
def <<(obj)
|
7
|
+
to_list << obj
|
8
|
+
end
|
9
|
+
|
10
|
+
def maybe?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_list
|
15
|
+
List.new(to_a)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_maybe
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def maybe(&blk)
|
23
|
+
bind(blk)
|
24
|
+
end
|
25
|
+
|
26
|
+
def then(fn)
|
27
|
+
bind(->(x){ fn && fn.call })
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def and(&blk)
|
32
|
+
self.then(blk)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def initialize; end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/monad/maybe/json.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
#
|
4
|
-
# Adds JSON conversions to Just, Nothing, and List
|
5
|
-
#
|
6
|
-
module Monad
|
7
|
-
module Maybe
|
8
|
-
class Just
|
9
|
-
def to_json(*args)
|
10
|
-
value.to_json(*args)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Nothing
|
15
|
-
def to_json(*args)
|
16
|
-
'null'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class List
|
21
|
-
def to_json(*args)
|
22
|
-
to_a.to_json(*args)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Adds JSON conversions to Just, Nothing, and List
|
5
|
+
#
|
6
|
+
module Monad
|
7
|
+
module Maybe
|
8
|
+
class Just
|
9
|
+
def to_json(*args)
|
10
|
+
value.to_json(*args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Nothing
|
15
|
+
def to_json(*args)
|
16
|
+
'null'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class List
|
21
|
+
def to_json(*args)
|
22
|
+
to_a.to_json(*args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/monad/maybe/just.rb
CHANGED
@@ -1,62 +1,62 @@
|
|
1
|
-
module Monad
|
2
|
-
module Maybe
|
3
|
-
class Just < Base
|
4
|
-
def initialize(value)
|
5
|
-
@value = value
|
6
|
-
end
|
7
|
-
|
8
|
-
def method_missing(method, *args)
|
9
|
-
value.send(method, *args).to_maybe
|
10
|
-
end
|
11
|
-
|
12
|
-
def unwrap(val)
|
13
|
-
value
|
14
|
-
end
|
15
|
-
|
16
|
-
def nothing?
|
17
|
-
false
|
18
|
-
end
|
19
|
-
|
20
|
-
def something?
|
21
|
-
true
|
22
|
-
end
|
23
|
-
|
24
|
-
def just?
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
def bind(fn)
|
29
|
-
fn[@value].to_maybe
|
30
|
-
end
|
31
|
-
|
32
|
-
def nil?
|
33
|
-
false
|
34
|
-
end
|
35
|
-
|
36
|
-
def ==(other)
|
37
|
-
self === other || self.value == other
|
38
|
-
end
|
39
|
-
|
40
|
-
def ===(other)
|
41
|
-
other.just? && self.value == other.value
|
42
|
-
end
|
43
|
-
|
44
|
-
def equal?(other)
|
45
|
-
other.__id__ == self.__id__
|
46
|
-
end
|
47
|
-
|
48
|
-
def inspect
|
49
|
-
"just(#{value.inspect})"
|
50
|
-
end
|
51
|
-
|
52
|
-
def to_s
|
53
|
-
value.to_s
|
54
|
-
end
|
55
|
-
alias to_str to_s
|
56
|
-
|
57
|
-
def to_a
|
58
|
-
[self]
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
1
|
+
module Monad
|
2
|
+
module Maybe
|
3
|
+
class Just < Base
|
4
|
+
def initialize(value)
|
5
|
+
@value = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(method, *args)
|
9
|
+
value.send(method, *args).to_maybe
|
10
|
+
end
|
11
|
+
|
12
|
+
def unwrap(val)
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
def nothing?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def something?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def just?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def bind(fn)
|
29
|
+
fn[@value].to_maybe
|
30
|
+
end
|
31
|
+
|
32
|
+
def nil?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def ==(other)
|
37
|
+
self === other || self.value == other
|
38
|
+
end
|
39
|
+
|
40
|
+
def ===(other)
|
41
|
+
other.just? && self.value == other.value
|
42
|
+
end
|
43
|
+
|
44
|
+
def equal?(other)
|
45
|
+
other.__id__ == self.__id__
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
"just(#{value.inspect})"
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
value.to_s
|
54
|
+
end
|
55
|
+
alias to_str to_s
|
56
|
+
|
57
|
+
def to_a
|
58
|
+
[self]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/monad/maybe/list.rb
CHANGED
@@ -1,72 +1,72 @@
|
|
1
|
-
module Monad
|
2
|
-
module Maybe
|
3
|
-
class List
|
4
|
-
include Enumerable
|
5
|
-
|
6
|
-
def initialize(enum)
|
7
|
-
@enum = enum.map { |v| v.maybe? ? v : v.to_maybe }
|
8
|
-
end
|
9
|
-
|
10
|
-
def inspect
|
11
|
-
"#{to_a}"
|
12
|
-
end
|
13
|
-
|
14
|
-
def maybe?
|
15
|
-
true
|
16
|
-
end
|
17
|
-
|
18
|
-
def <<(obj)
|
19
|
-
@enum << obj if obj.just?
|
20
|
-
self
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_a
|
24
|
-
@enum.to_a
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_maybe
|
28
|
-
first.to_maybe
|
29
|
-
end
|
30
|
-
|
31
|
-
def each
|
32
|
-
@enum.each do |x|
|
33
|
-
yield(x)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def map
|
38
|
-
e = []
|
39
|
-
each do |x|
|
40
|
-
e << yield(x)
|
41
|
-
end
|
42
|
-
List.new(e)
|
43
|
-
end
|
44
|
-
alias maybe_map map
|
45
|
-
|
46
|
-
def select
|
47
|
-
e = []
|
48
|
-
each do |x|
|
49
|
-
is_true = yield(x)
|
50
|
-
e << x if is_true
|
51
|
-
end
|
52
|
-
List.new(e)
|
53
|
-
end
|
54
|
-
|
55
|
-
def reject
|
56
|
-
select { |x| !yield(x) }
|
57
|
-
end
|
58
|
-
|
59
|
-
def select_just
|
60
|
-
select { |x| x.just? }
|
61
|
-
end
|
62
|
-
|
63
|
-
def unwrap_map(default, &blk)
|
64
|
-
to_a.map { |x| blk ? blk.call(x.unwrap(default)) : x.unwrap(default) }
|
65
|
-
end
|
66
|
-
|
67
|
-
def value_map(&blk)
|
68
|
-
to_a.map { |x| blk ? blk.call(x.value) : x.value }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
1
|
+
module Monad
|
2
|
+
module Maybe
|
3
|
+
class List
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(enum)
|
7
|
+
@enum = enum.map { |v| v.maybe? ? v : v.to_maybe }
|
8
|
+
end
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"#{to_a}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def maybe?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def <<(obj)
|
19
|
+
@enum << obj if obj.just?
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_a
|
24
|
+
@enum.to_a
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_maybe
|
28
|
+
first.to_maybe
|
29
|
+
end
|
30
|
+
|
31
|
+
def each
|
32
|
+
@enum.each do |x|
|
33
|
+
yield(x)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def map
|
38
|
+
e = []
|
39
|
+
each do |x|
|
40
|
+
e << yield(x)
|
41
|
+
end
|
42
|
+
List.new(e)
|
43
|
+
end
|
44
|
+
alias maybe_map map
|
45
|
+
|
46
|
+
def select
|
47
|
+
e = []
|
48
|
+
each do |x|
|
49
|
+
is_true = yield(x)
|
50
|
+
e << x if is_true
|
51
|
+
end
|
52
|
+
List.new(e)
|
53
|
+
end
|
54
|
+
|
55
|
+
def reject
|
56
|
+
select { |x| !yield(x) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def select_just
|
60
|
+
select { |x| x.just? }
|
61
|
+
end
|
62
|
+
|
63
|
+
def unwrap_map(default, &blk)
|
64
|
+
to_a.map { |x| blk ? blk.call(x.unwrap(default)) : x.unwrap(default) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def value_map(&blk)
|
68
|
+
to_a.map { |x| blk ? blk.call(x.value) : x.value }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/monad/maybe/nothing.rb
CHANGED
@@ -1,58 +1,58 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
module Monad
|
4
|
-
module Maybe
|
5
|
-
class Nothing < Base
|
6
|
-
include ::Singleton
|
7
|
-
|
8
|
-
def method_missing(method, *args)
|
9
|
-
self
|
10
|
-
end
|
11
|
-
|
12
|
-
def clone
|
13
|
-
self
|
14
|
-
end
|
15
|
-
|
16
|
-
def inspect
|
17
|
-
'nothing'
|
18
|
-
end
|
19
|
-
|
20
|
-
def nil?
|
21
|
-
true
|
22
|
-
end
|
23
|
-
|
24
|
-
def nothing?
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
def bind(fn)
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def just?
|
33
|
-
false
|
34
|
-
end
|
35
|
-
|
36
|
-
def something?
|
37
|
-
false
|
38
|
-
end
|
39
|
-
|
40
|
-
def unwrap(val)
|
41
|
-
val
|
42
|
-
end
|
43
|
-
|
44
|
-
def value
|
45
|
-
nil
|
46
|
-
end
|
47
|
-
|
48
|
-
def to_s
|
49
|
-
''
|
50
|
-
end
|
51
|
-
alias to_str to_s
|
52
|
-
|
53
|
-
def to_a
|
54
|
-
[]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Monad
|
4
|
+
module Maybe
|
5
|
+
class Nothing < Base
|
6
|
+
include ::Singleton
|
7
|
+
|
8
|
+
def method_missing(method, *args)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def clone
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
'nothing'
|
18
|
+
end
|
19
|
+
|
20
|
+
def nil?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def nothing?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def bind(fn)
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def just?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def something?
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def unwrap(val)
|
41
|
+
val
|
42
|
+
end
|
43
|
+
|
44
|
+
def value
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
''
|
50
|
+
end
|
51
|
+
alias to_str to_s
|
52
|
+
|
53
|
+
def to_a
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/monad-maybe.gemspec
CHANGED
@@ -1,56 +1,57 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = "monad-maybe"
|
8
|
-
s.version = "0.9.
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Delon Newman"]
|
12
|
-
s.date = "2013-08-
|
13
|
-
s.description = "This is an attempt to implement Haskell's Maybe monad in a Ruby-ish way."
|
14
|
-
s.email = "delon.newman@gmail.com"
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"README.md"
|
17
|
-
]
|
18
|
-
s.files = [
|
19
|
-
"Gemfile",
|
20
|
-
"Gemfile.lock",
|
21
|
-
"README.md",
|
22
|
-
"Rakefile",
|
23
|
-
"VERSION",
|
24
|
-
"lib/monad/maybe.rb",
|
25
|
-
"lib/monad/maybe/base.rb",
|
26
|
-
"lib/monad/maybe/json.rb",
|
27
|
-
"lib/monad/maybe/just.rb",
|
28
|
-
"lib/monad/maybe/list.rb",
|
29
|
-
"lib/monad/maybe/nothing.rb",
|
30
|
-
"monad-maybe.gemspec",
|
31
|
-
"test/maybe.rb"
|
32
|
-
]
|
33
|
-
s.homepage = "https://github.com/delonnewman/monad-maybe"
|
34
|
-
s.
|
35
|
-
s.
|
36
|
-
s.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
s.add_development_dependency(%q<
|
44
|
-
s.add_development_dependency(%q<
|
45
|
-
|
46
|
-
|
47
|
-
s.add_dependency(%q<
|
48
|
-
s.add_dependency(%q<
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
s.add_dependency(%q<
|
53
|
-
s.add_dependency(%q<
|
54
|
-
|
55
|
-
end
|
56
|
-
|
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 = "monad-maybe"
|
8
|
+
s.version = "0.9.9"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Delon Newman"]
|
12
|
+
s.date = "2013-08-18"
|
13
|
+
s.description = "This is an attempt to implement Haskell's Maybe monad in a Ruby-ish way."
|
14
|
+
s.email = "delon.newman@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"Gemfile",
|
20
|
+
"Gemfile.lock",
|
21
|
+
"README.md",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"lib/monad/maybe.rb",
|
25
|
+
"lib/monad/maybe/base.rb",
|
26
|
+
"lib/monad/maybe/json.rb",
|
27
|
+
"lib/monad/maybe/just.rb",
|
28
|
+
"lib/monad/maybe/list.rb",
|
29
|
+
"lib/monad/maybe/nothing.rb",
|
30
|
+
"monad-maybe.gemspec",
|
31
|
+
"test/maybe.rb"
|
32
|
+
]
|
33
|
+
s.homepage = "https://github.com/delonnewman/monad-maybe"
|
34
|
+
s.licenses = ["MIT"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = "2.0.0.rc.2"
|
37
|
+
s.summary = "A Ruby implementation of Haskell's Maybe Monad"
|
38
|
+
|
39
|
+
if s.respond_to? :specification_version then
|
40
|
+
s.specification_version = 4
|
41
|
+
|
42
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
44
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
45
|
+
s.add_development_dependency(%q<test-unit>, [">= 0"])
|
46
|
+
else
|
47
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
48
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
49
|
+
s.add_dependency(%q<test-unit>, [">= 0"])
|
50
|
+
end
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
53
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
54
|
+
s.add_dependency(%q<test-unit>, [">= 0"])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/test/maybe.rb
CHANGED
@@ -1,158 +1,158 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require_relative '../lib/monad/maybe'
|
3
|
-
require_relative '../lib/monad/maybe/json'
|
4
|
-
|
5
|
-
class MaybeTest < Test::Unit::TestCase
|
6
|
-
def test_nothing
|
7
|
-
assert nil.to_maybe.nothing?
|
8
|
-
assert nil.to_maybe.value.nil?
|
9
|
-
assert_equal 'test', nil.to_maybe.unwrap('test')
|
10
|
-
assert_equal '', nothing.to_s
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_just
|
14
|
-
assert maybe(1).just?
|
15
|
-
assert_equal 1, 1.to_maybe.value
|
16
|
-
assert_equal 1, 1.to_maybe.unwrap('test')
|
17
|
-
assert_equal '1', just(1).to_s
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_json
|
21
|
-
assert_equal 'null', nothing.to_json
|
22
|
-
assert_equal '1', just(1).to_json
|
23
|
-
assert_equal '{}', just({}).to_json
|
24
|
-
assert_equal '[]', just([]).to_json
|
25
|
-
assert_equal (0..10).to_a.to_json, (0..10).maybe_map { |n| n }.to_json
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_to_a
|
29
|
-
assert_equal [1.to_maybe], 1.to_maybe.to_a
|
30
|
-
assert_equal [], nil.to_maybe.to_a
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_false
|
34
|
-
assert_equal false, false.to_maybe.value
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_nil_conversions
|
38
|
-
assert_equal nil.nil?, nil.to_maybe.nil?
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_class
|
42
|
-
assert_equal Monad::Maybe::Nothing, maybe(nil).class
|
43
|
-
assert_equal Monad::Maybe::Just, maybe(1).class
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_list
|
47
|
-
xs = true.to_maybe << nil.to_maybe << 1.to_maybe << 3.to_maybe
|
48
|
-
assert_equal 3, xs.count
|
49
|
-
xs.each { |x| assert x.just? }
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_enumerable
|
53
|
-
assert_nothing_raised do
|
54
|
-
xs = (0..10).select { |n| n % 2 != 0 }
|
55
|
-
ys = (0..10).maybe_map { |n| n % 2 == 0 ? nil : n }.select_just.value_map
|
56
|
-
assert_equal xs.count, ys.count
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_maybe_block
|
61
|
-
assert_nothing_raised do
|
62
|
-
nothing.maybe do
|
63
|
-
raise Exception, "This should not be called"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
assert_nothing_raised do
|
68
|
-
maybe(nil) do
|
69
|
-
raise Exception, "This should not be called"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
maybe(1) do |n|
|
74
|
-
assert_equal 1, n
|
75
|
-
end
|
76
|
-
|
77
|
-
just(1).maybe do |n|
|
78
|
-
assert_equal 1, n
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_to_maybe_blocks
|
83
|
-
1.to_maybe { |v| assert_equal 1, v }
|
84
|
-
|
85
|
-
assert_nothing_raised do
|
86
|
-
nil.to_maybe { raise Exception, "This should not run" }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
def test_maybe_block_return_value_and_type
|
92
|
-
m = maybe(1).maybe { |n| n + 1 }
|
93
|
-
assert_equal 2, m.value
|
94
|
-
assert m.maybe?
|
95
|
-
assert m.just?
|
96
|
-
|
97
|
-
o = maybe(2).maybe { nil }
|
98
|
-
assert_equal nil, o.value
|
99
|
-
assert o.maybe?
|
100
|
-
assert o.nothing?
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_to_maybe
|
104
|
-
assert_equal just(1), 1.to_maybe
|
105
|
-
assert_equal just(1), just(1).to_maybe
|
106
|
-
assert_equal nothing, nil.to_maybe
|
107
|
-
assert_equal nothing, nothing.to_maybe
|
108
|
-
assert_equal 1.to_maybe, [1].to_maybe
|
109
|
-
assert_equal 0.to_maybe, (0..10).maybe_map { |n| n }.to_maybe
|
110
|
-
end
|
111
|
-
|
112
|
-
def test_then_and_and
|
113
|
-
just(1).and do
|
114
|
-
assert true
|
115
|
-
end
|
116
|
-
|
117
|
-
nothing.and do
|
118
|
-
assert true
|
119
|
-
end
|
120
|
-
|
121
|
-
just(1).and{ assert true }.and{ assert true }
|
122
|
-
maybe(1).then(->(){ assert true }).then(->(){ assert true })
|
123
|
-
end
|
124
|
-
|
125
|
-
#
|
126
|
-
# Monad laws
|
127
|
-
#
|
128
|
-
|
129
|
-
#
|
130
|
-
# Right Unit:
|
131
|
-
# m >>= return = m
|
132
|
-
#
|
133
|
-
def test_right_unit
|
134
|
-
m = just(1)
|
135
|
-
assert_equal m, m.bind(->(x){ Monad::Maybe.return(x) })
|
136
|
-
end
|
137
|
-
|
138
|
-
#
|
139
|
-
# Left Unit:
|
140
|
-
# return x >>= f = f x
|
141
|
-
#
|
142
|
-
def test_left_unit
|
143
|
-
x = 2
|
144
|
-
f = ->(x) { x + 1 }
|
145
|
-
assert_equal Monad::Maybe.return(x).bind(f), f[x]
|
146
|
-
end
|
147
|
-
|
148
|
-
#
|
149
|
-
# Associativity:
|
150
|
-
# (m >>= f) >>= g = m >>= (\x -> f x >>= g)
|
151
|
-
#
|
152
|
-
def test_associativity
|
153
|
-
m = just(3.1459)
|
154
|
-
f = ->(x) { x ** 2 }
|
155
|
-
g = ->(x) { 2 * x }
|
156
|
-
assert_equal m.bind(f).bind(g), m.bind(->(x) { f[x] }).bind(g)
|
157
|
-
end
|
158
|
-
end
|
1
|
+
require 'test/unit'
|
2
|
+
require_relative '../lib/monad/maybe'
|
3
|
+
require_relative '../lib/monad/maybe/json'
|
4
|
+
|
5
|
+
class MaybeTest < Test::Unit::TestCase
|
6
|
+
def test_nothing
|
7
|
+
assert nil.to_maybe.nothing?
|
8
|
+
assert nil.to_maybe.value.nil?
|
9
|
+
assert_equal 'test', nil.to_maybe.unwrap('test')
|
10
|
+
assert_equal '', nothing.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_just
|
14
|
+
assert maybe(1).just?
|
15
|
+
assert_equal 1, 1.to_maybe.value
|
16
|
+
assert_equal 1, 1.to_maybe.unwrap('test')
|
17
|
+
assert_equal '1', just(1).to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_json
|
21
|
+
assert_equal 'null', nothing.to_json
|
22
|
+
assert_equal '1', just(1).to_json
|
23
|
+
assert_equal '{}', just({}).to_json
|
24
|
+
assert_equal '[]', just([]).to_json
|
25
|
+
assert_equal (0..10).to_a.to_json, (0..10).maybe_map { |n| n }.to_json
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_to_a
|
29
|
+
assert_equal [1.to_maybe], 1.to_maybe.to_a
|
30
|
+
assert_equal [], nil.to_maybe.to_a
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_false
|
34
|
+
assert_equal false, false.to_maybe.value
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_nil_conversions
|
38
|
+
assert_equal nil.nil?, nil.to_maybe.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_class
|
42
|
+
assert_equal Monad::Maybe::Nothing, maybe(nil).class
|
43
|
+
assert_equal Monad::Maybe::Just, maybe(1).class
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_list
|
47
|
+
xs = true.to_maybe << nil.to_maybe << 1.to_maybe << 3.to_maybe
|
48
|
+
assert_equal 3, xs.count
|
49
|
+
xs.each { |x| assert x.just? }
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_enumerable
|
53
|
+
assert_nothing_raised do
|
54
|
+
xs = (0..10).select { |n| n % 2 != 0 }
|
55
|
+
ys = (0..10).maybe_map { |n| n % 2 == 0 ? nil : n }.select_just.value_map
|
56
|
+
assert_equal xs.count, ys.count
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_maybe_block
|
61
|
+
assert_nothing_raised do
|
62
|
+
nothing.maybe do
|
63
|
+
raise Exception, "This should not be called"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
assert_nothing_raised do
|
68
|
+
maybe(nil) do
|
69
|
+
raise Exception, "This should not be called"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
maybe(1) do |n|
|
74
|
+
assert_equal 1, n
|
75
|
+
end
|
76
|
+
|
77
|
+
just(1).maybe do |n|
|
78
|
+
assert_equal 1, n
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_to_maybe_blocks
|
83
|
+
1.to_maybe { |v| assert_equal 1, v }
|
84
|
+
|
85
|
+
assert_nothing_raised do
|
86
|
+
nil.to_maybe { raise Exception, "This should not run" }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def test_maybe_block_return_value_and_type
|
92
|
+
m = maybe(1).maybe { |n| n + 1 }
|
93
|
+
assert_equal 2, m.value
|
94
|
+
assert m.maybe?
|
95
|
+
assert m.just?
|
96
|
+
|
97
|
+
o = maybe(2).maybe { nil }
|
98
|
+
assert_equal nil, o.value
|
99
|
+
assert o.maybe?
|
100
|
+
assert o.nothing?
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_to_maybe
|
104
|
+
assert_equal just(1), 1.to_maybe
|
105
|
+
assert_equal just(1), just(1).to_maybe
|
106
|
+
assert_equal nothing, nil.to_maybe
|
107
|
+
assert_equal nothing, nothing.to_maybe
|
108
|
+
assert_equal 1.to_maybe, [1].to_maybe
|
109
|
+
assert_equal 0.to_maybe, (0..10).maybe_map { |n| n }.to_maybe
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_then_and_and
|
113
|
+
just(1).and do
|
114
|
+
assert true
|
115
|
+
end
|
116
|
+
|
117
|
+
nothing.and do
|
118
|
+
assert true
|
119
|
+
end
|
120
|
+
|
121
|
+
just(1).and{ assert true }.and{ assert true }
|
122
|
+
maybe(1).then(->(){ assert true }).then(->(){ assert true })
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Monad laws
|
127
|
+
#
|
128
|
+
|
129
|
+
#
|
130
|
+
# Right Unit:
|
131
|
+
# m >>= return = m
|
132
|
+
#
|
133
|
+
def test_right_unit
|
134
|
+
m = just(1)
|
135
|
+
assert_equal m, m.bind(->(x){ Monad::Maybe.return(x) })
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Left Unit:
|
140
|
+
# return x >>= f = f x
|
141
|
+
#
|
142
|
+
def test_left_unit
|
143
|
+
x = 2
|
144
|
+
f = ->(x) { x + 1 }
|
145
|
+
assert_equal Monad::Maybe.return(x).bind(f), f[x]
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Associativity:
|
150
|
+
# (m >>= f) >>= g = m >>= (\x -> f x >>= g)
|
151
|
+
#
|
152
|
+
def test_associativity
|
153
|
+
m = just(3.1459)
|
154
|
+
f = ->(x) { x ** 2 }
|
155
|
+
g = ->(x) { 2 * x }
|
156
|
+
assert_equal m.bind(f).bind(g), m.bind(->(x) { f[x] }).bind(g)
|
157
|
+
end
|
158
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monad-maybe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delon Newman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jeweler
|
@@ -73,7 +73,8 @@ files:
|
|
73
73
|
- monad-maybe.gemspec
|
74
74
|
- test/maybe.rb
|
75
75
|
homepage: https://github.com/delonnewman/monad-maybe
|
76
|
-
licenses:
|
76
|
+
licenses:
|
77
|
+
- MIT
|
77
78
|
metadata: {}
|
78
79
|
post_install_message:
|
79
80
|
rdoc_options: []
|
@@ -91,9 +92,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
92
|
version: '0'
|
92
93
|
requirements: []
|
93
94
|
rubyforge_project:
|
94
|
-
rubygems_version: 2.0.0
|
95
|
+
rubygems_version: 2.0.0.rc.2
|
95
96
|
signing_key:
|
96
97
|
specification_version: 4
|
97
98
|
summary: A Ruby implementation of Haskell's Maybe Monad
|
98
99
|
test_files: []
|
99
|
-
has_rdoc:
|