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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9b624308416ed8b74db359022fe3cbc65c63e5b
4
- data.tar.gz: d03ab54204740c3c608e4bc5faea88952cb373de
3
+ metadata.gz: 96a1150eee677ad2091303f4306c9d4ed498f5f5
4
+ data.tar.gz: 27f9c68387c3e40c14cd2f5702b38dee7a168188
5
5
  SHA512:
6
- metadata.gz: 67d3f7414267af4083a86ad199fbabf76eefcd5414edb62345141b9c848c686bdc59f4e0bce496e13b6aacb8e4097c095fe895f26bf9e44bb3f7dfab73155651
7
- data.tar.gz: dcb5d360e0475ffdcdbd7c222b1f25e23d2e5f1f3b73fa9a4747511cdb72a543752fc292cf721f37a2694f765776163a7d45cc7b1c9f4106ec76dfe290ac26c0
6
+ metadata.gz: f93b06a4f7a3eb276cb87817e86be45d3355c3e3f1af5452fd69926c7e7e0de6327185e396cc6b6e151f766697cbf176a8885267994ce4d43c57d32049a27383
7
+ data.tar.gz: 0a8a459bd7e25d29f499229fc18b7c05aa29b151139802e5e249e9a052e62101ab34c633ce776db3537256abe200216e225a6e4d7a575bfe9038a6cb4cb4a903
@@ -0,0 +1,9 @@
1
+ # Changes
2
+
3
+ ## 0.1.1
4
+
5
+ * [Add `lift` method to Maybe](https://github.com/kickstarter/ruby-maybe/pull/7)
6
+
7
+ ## 0.1.0
8
+
9
+ * Initial implementation
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
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ksr-maybe'
3
- s.version = '0.1.0'
3
+ s.version = '0.1.1'
4
4
  s.summary = 'A library providing the optional type \'Maybe\''
5
5
  s.authors = ['Ryan Closner', 'Corey Farwell']
6
6
  s.email = 'eng@kickstarter.com'
@@ -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(of([])) do |accum, maybe|
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.
@@ -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.0
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-06-26 00:00:00.000000000 Z
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.0.14.1
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'