ksr-maybe 0.1.0 → 0.1.1
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/CHANGES.md +9 -0
- data/README.md +41 -0
- data/ksr-maybe.gemspec +1 -1
- data/lib/maybe.rb +42 -1
- data/test/maybe_test.rb +33 -0
- metadata +15 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96a1150eee677ad2091303f4306c9d4ed498f5f5
|
4
|
+
data.tar.gz: 27f9c68387c3e40c14cd2f5702b38dee7a168188
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f93b06a4f7a3eb276cb87817e86be45d3355c3e3f1af5452fd69926c7e7e0de6327185e396cc6b6e151f766697cbf176a8885267994ce4d43c57d32049a27383
|
7
|
+
data.tar.gz: 0a8a459bd7e25d29f499229fc18b7c05aa29b151139802e5e249e9a052e62101ab34c633ce776db3537256abe200216e225a6e4d7a575bfe9038a6cb4cb4a903
|
data/CHANGES.md
ADDED
data/README.md
CHANGED
@@ -3,6 +3,47 @@
|
|
3
3
|
This gem provides a `Maybe` type. The `Maybe` type either contains a value
|
4
4
|
(represented as `Just`) or it is empty (represented as `Nothing`).
|
5
5
|
|
6
|
+
# Installation
|
7
|
+
|
8
|
+
Install the `ksr-maybe` gem, or add it to your Gemfile with bundler:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
# In your Gemfile
|
12
|
+
gem 'ksr-maybe'
|
13
|
+
```
|
14
|
+
|
15
|
+
# Usage
|
16
|
+
|
17
|
+
Maybe is useful for handling potentially null values:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
User = Struct.new(:email, :name)
|
21
|
+
|
22
|
+
users = [
|
23
|
+
User.new("jane@doe.com", "Jane Doe"),
|
24
|
+
User.new("john@doe.com", "John Doe")
|
25
|
+
]
|
26
|
+
|
27
|
+
# When value is not null
|
28
|
+
|
29
|
+
user = users.find { |user| user.email == "jane@doe.com" }
|
30
|
+
|
31
|
+
Maybe.from_nullable(user)
|
32
|
+
.map { |user| user.name }
|
33
|
+
.get_or_else { "User not found" }
|
34
|
+
|
35
|
+
#=> "Jane Doe"
|
36
|
+
|
37
|
+
# When value is null
|
38
|
+
|
39
|
+
user = users.find { |user| user.email == "not@present.com" }
|
40
|
+
|
41
|
+
Maybe.from_nullable(user)
|
42
|
+
.map { |user| user.name }
|
43
|
+
.get_or_else { "User not found" }
|
44
|
+
|
45
|
+
#=> "User not found"
|
46
|
+
```
|
6
47
|
|
7
48
|
## Contracts
|
8
49
|
|
data/ksr-maybe.gemspec
CHANGED
data/lib/maybe.rb
CHANGED
@@ -129,12 +129,53 @@ module Maybe
|
|
129
129
|
# @return [Just<Any>,Nothing] either a combined Just, or Nothing
|
130
130
|
Contract C::Args[Maybe] => C::Or[Maybe]
|
131
131
|
def self.zip(fst, snd, *rest)
|
132
|
-
[fst, snd, *rest].reduce(
|
132
|
+
[fst, snd, *rest].reduce(Just([])) do |accum, maybe|
|
133
133
|
accum.flat_map do |accum_|
|
134
134
|
maybe.map {|maybe_| accum_ + [maybe_] }
|
135
135
|
end
|
136
136
|
end
|
137
137
|
end
|
138
|
+
|
139
|
+
# Takes a function and a set of Maybes, and attempts to apply the function
|
140
|
+
# and return the result wrapped in a Maybe.
|
141
|
+
#
|
142
|
+
# @example with a single instance of Just
|
143
|
+
# Maybe.lift(->(n){ n ** 2 }, Maybe.Just(3))
|
144
|
+
# #=> Just(9)
|
145
|
+
#
|
146
|
+
# @example with a single instance of Nothing
|
147
|
+
# Maybe.lift(->(n){ n ** 2 }, Maybe.Nothing)
|
148
|
+
# #=> Nothing
|
149
|
+
#
|
150
|
+
# @example with multiple instances of Just
|
151
|
+
# Maybe.lift(->(x,y){ x + y }, Maybe.Just(1), Maybe.Just(2))
|
152
|
+
# #=> Just(3)
|
153
|
+
#
|
154
|
+
# @example with multiple instances of Nothing
|
155
|
+
# Maybe.lift(->(x,y){ x + y }, Maybe.Nothing, Maybe.Nothing)
|
156
|
+
# #=> Nothing
|
157
|
+
#
|
158
|
+
# @example a mixture of Just and Nothing instances
|
159
|
+
# Maybe.lift(->(x,y,z) { x + y + z }, Maybe.Just(1), Maybe.Nothing, Maybe.Just(2))
|
160
|
+
# #=> Nothing
|
161
|
+
#
|
162
|
+
# @example called with the wrong number of arguments
|
163
|
+
# Maybe.lift(->(x,y) { x + y }, Maybe.Just(1))
|
164
|
+
# #=> ArgumentError: wrong number of arguments (given 1, expected 2)
|
165
|
+
#
|
166
|
+
# @param f [Proc] a function
|
167
|
+
# @param m [Array<Just<Any>>, Array<Nothing>] a collection of Maybes
|
168
|
+
# @return [Just<Any>,Nothing] either the result wrapped in a Just, or Nothing
|
169
|
+
Contract Proc, C::Args[Maybe] => Maybe
|
170
|
+
def self.lift(f, fst, *rst)
|
171
|
+
[fst, *rst]
|
172
|
+
.reduce(Just([])) {|accum, maybe|
|
173
|
+
accum.flat_map {|accum_|
|
174
|
+
maybe.map {|maybe_| accum_ + [maybe_] }
|
175
|
+
}
|
176
|
+
}
|
177
|
+
.ap( Just(->(args){ f.call(*args) }) )
|
178
|
+
end
|
138
179
|
end
|
139
180
|
|
140
181
|
# Nothing is a member of the Maybe union type that represents a null value.
|
data/test/maybe_test.rb
CHANGED
@@ -61,6 +61,39 @@ class MaybeTest < Minitest::Test
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
context ".lift" do
|
65
|
+
setup do
|
66
|
+
@add = ->(x,y){ x + y }
|
67
|
+
@squared = ->(x){ x ** 2 }
|
68
|
+
@maybe_x = Maybe.Just(2)
|
69
|
+
@maybe_y = Maybe.Just(3)
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with the wrong number of arguments" do
|
73
|
+
should "raise an error" do
|
74
|
+
assert_raises(ArgumentError) { Maybe.lift(@add, @maybe_x) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with a single Just value" do
|
79
|
+
should "return an instance of Just" do
|
80
|
+
assert_equal Maybe.Just(9), Maybe.lift(@squared, @maybe_y)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "with multiple Just values" do
|
85
|
+
should "return an instance of Just" do
|
86
|
+
assert_equal Maybe.Just(5), Maybe.lift(@add, @maybe_x, @maybe_y)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "with a Nothing value" do
|
91
|
+
should "return an instance of Just" do
|
92
|
+
assert_equal Nothing.instance, Maybe.lift(@add, @maybe_x, Nothing.instance)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
64
97
|
context "Nothing" do
|
65
98
|
subject do
|
66
99
|
Nothing.instance
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ksr-maybe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Closner
|
@@ -9,62 +9,62 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-07-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: contracts
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - ~>
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 0.16.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - ~>
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 0.16.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: shoulda-context
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - ~>
|
32
|
+
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '1.2'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - ~>
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '1.2'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: minitest
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - ~>
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '5.10'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - ~>
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '5.10'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: rake
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - ~>
|
60
|
+
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '12.0'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - ~>
|
67
|
+
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '12.0'
|
70
70
|
description:
|
@@ -73,7 +73,8 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
- .gitignore
|
76
|
+
- ".gitignore"
|
77
|
+
- CHANGES.md
|
77
78
|
- Gemfile
|
78
79
|
- LICENSE
|
79
80
|
- NOTICE.md
|
@@ -93,17 +94,17 @@ require_paths:
|
|
93
94
|
- lib
|
94
95
|
required_ruby_version: !ruby/object:Gem::Requirement
|
95
96
|
requirements:
|
96
|
-
- -
|
97
|
+
- - ">="
|
97
98
|
- !ruby/object:Gem::Version
|
98
99
|
version: '0'
|
99
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
101
|
requirements:
|
101
|
-
- -
|
102
|
+
- - ">="
|
102
103
|
- !ruby/object:Gem::Version
|
103
104
|
version: '0'
|
104
105
|
requirements: []
|
105
106
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.4.5.2
|
107
108
|
signing_key:
|
108
109
|
specification_version: 4
|
109
110
|
summary: A library providing the optional type 'Maybe'
|