dry-monads 1.1.0 → 1.2.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 +4 -4
- data/.travis.yml +6 -6
- data/CHANGELOG.md +90 -0
- data/dry-monads.gemspec +1 -1
- data/lib/dry/monads.rb +42 -2
- data/lib/dry/monads/all.rb +3 -20
- data/lib/dry/monads/do/all.rb +8 -0
- data/lib/dry/monads/lazy.rb +2 -1
- data/lib/dry/monads/list.rb +36 -0
- data/lib/dry/monads/maybe.rb +3 -0
- data/lib/dry/monads/registry.rb +70 -0
- data/lib/dry/monads/result.rb +5 -0
- data/lib/dry/monads/right_biased.rb +59 -1
- data/lib/dry/monads/task.rb +11 -2
- data/lib/dry/monads/try.rb +4 -1
- data/lib/dry/monads/validated.rb +3 -0
- data/lib/dry/monads/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae0ce757dc3f6ec60e8fb1d3e111535fe3e32d40956c5e38cdbef583805b5f6a
|
4
|
+
data.tar.gz: 83962c10f05f0a53d37a34c77c4197a799a8a78f7a6de767999a6eebd0f30571
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1754fea24d90657ea3947de3c1b4206d22c977ec30546377ccb82c166a898ca8f4dc0b6b21dd384ceea78a706c29c9570951222f48e6a40b661964b1f43ffef2
|
7
|
+
data.tar.gz: 7667bcb8d8a009f68055c9cade624e7276a51749f42fdbfacc8e47b13763e10f57e7e34b00878017498f100f9eae55de72e10b9d8ffcad8d952043311aea74ed
|
data/.travis.yml
CHANGED
@@ -7,15 +7,15 @@ script:
|
|
7
7
|
- bundle exec rake spec
|
8
8
|
before_install:
|
9
9
|
- gem update --system
|
10
|
+
- gem install bundler
|
10
11
|
after_success:
|
11
12
|
- '[ -d coverage ] && bundle exec codeclimate-test-reporter'
|
12
13
|
rvm:
|
13
|
-
- 2.
|
14
|
-
- 2.
|
15
|
-
- 2.
|
16
|
-
- 2.
|
17
|
-
- jruby-9.2.
|
18
|
-
- ruby-head
|
14
|
+
- 2.3.8
|
15
|
+
- 2.4.5
|
16
|
+
- 2.5.3
|
17
|
+
- 2.6.0
|
18
|
+
- jruby-9.2.4.0
|
19
19
|
env:
|
20
20
|
global:
|
21
21
|
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,93 @@
|
|
1
|
+
# v1.2.0 2019-01-12
|
2
|
+
|
3
|
+
## BREAKING CHANGES
|
4
|
+
|
5
|
+
* Support for Ruby 2.2 was dropped. Ruby 2.2 reached its EOL on March 31, 2018.
|
6
|
+
|
7
|
+
## Added
|
8
|
+
|
9
|
+
* Most of constructors now have `call` alias so you can compose them with Procs nicely if you've switched to Ruby 2.6 (flash-gordon)
|
10
|
+
```ruby
|
11
|
+
pipe = -> x { x.upcase } >> Success
|
12
|
+
pipe.('foo') # => Success('FOO')
|
13
|
+
```
|
14
|
+
* `List#collect` gathers `Some` values from the list (flash-gordon)
|
15
|
+
```ruby
|
16
|
+
include Dry::Monads::List::Mixin
|
17
|
+
include Dry::Monads::Maybe::Mixin
|
18
|
+
# ...
|
19
|
+
List[10, 5, 0].collect do |divisor|
|
20
|
+
if divisor.zero?
|
21
|
+
None()
|
22
|
+
else
|
23
|
+
Some(n / divisor)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
# => List[4, 2]
|
27
|
+
```
|
28
|
+
|
29
|
+
Without block:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
List[Some(5), None(), Some(3)].collect.map { |x| x * 2 }
|
33
|
+
# => [10, 6]
|
34
|
+
```
|
35
|
+
|
36
|
+
* Right-biased monads got `#flatten` and `#and` (falsh-gordon)
|
37
|
+
|
38
|
+
`#flatten` removes one level of monadic structure, it's useful when you're dealing with things like `Maybe` of `Maybe` of something:
|
39
|
+
```ruby
|
40
|
+
include Dry::Monads::Maybe::Mixin
|
41
|
+
|
42
|
+
Some(Some(1)).flatten # => Some(1)
|
43
|
+
Some(None()).flatten # => None
|
44
|
+
None().flatten # => None
|
45
|
+
```
|
46
|
+
In contrast to `Array#flatten`, dry-monads' version removes only 1 level of nesting, that is always acts as `Array#flatten(1)`:
|
47
|
+
```ruby
|
48
|
+
Some(Some(Some(1))).flatten # => Some(Some(1))
|
49
|
+
```
|
50
|
+
`#and` is handy for combining two monadic values and working with them at once:
|
51
|
+
```ruby
|
52
|
+
include Dry::Monads::Maybe::Mixin
|
53
|
+
|
54
|
+
# using block
|
55
|
+
Some(5).and(Some(3)) { |x, y| x + y } # => Some(8)
|
56
|
+
# without block
|
57
|
+
Some(5).and(Some(3)) # => Some([5, 3])
|
58
|
+
# other cases
|
59
|
+
Some(5).and(None()) # => None()
|
60
|
+
None().and(Some(5)) # => None()
|
61
|
+
```
|
62
|
+
|
63
|
+
* Concise imports with `Dry::Monads.[]`. You're no longer required to require all desired monads and include them one-by-one, the `[]` method handles it for you (flash-gordon)
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
require 'dry/monads'
|
67
|
+
|
68
|
+
class CreateUser
|
69
|
+
include Dry::Monads[:result, :do]
|
70
|
+
|
71
|
+
def initialize(repo, send_email)
|
72
|
+
@repo = repo
|
73
|
+
@send_email = send_email
|
74
|
+
end
|
75
|
+
|
76
|
+
def call(name)
|
77
|
+
if @repo.user_exist?(name)
|
78
|
+
Failure(:user_exists)
|
79
|
+
else
|
80
|
+
user = yield @repo.add_user(name)
|
81
|
+
yield @send_email.(user)
|
82
|
+
Success(user)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
```
|
87
|
+
* `Task.failed` is a counterpart of `Task.pure`, accepts an exception and returns a failed task immediately (flash-gordon)
|
88
|
+
|
89
|
+
[Compare v1.1.0...v1.2.0](https://github.com/dry-rb/dry-monads/compare/v1.1.0...v1.2.0)
|
90
|
+
|
1
91
|
# v1.1.0 2018-10-16
|
2
92
|
|
3
93
|
## Fixed
|
data/dry-monads.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.bindir = 'exe'
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ['lib']
|
28
|
-
spec.required_ruby_version = ">= 2.
|
28
|
+
spec.required_ruby_version = ">= 2.3.0"
|
29
29
|
spec.add_dependency 'dry-equalizer'
|
30
30
|
spec.add_dependency 'dry-core', '~> 0.4', '>= 0.4.4'
|
31
31
|
spec.add_dependency 'concurrent-ruby', '~> 1.0'
|
data/lib/dry/monads.rb
CHANGED
@@ -1,14 +1,54 @@
|
|
1
|
+
require 'dry/monads/registry'
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
# Common, idiomatic monads for Ruby
|
3
5
|
#
|
4
6
|
# @api public
|
5
7
|
module Monads
|
6
8
|
def self.included(base)
|
7
|
-
if
|
8
|
-
base.include(*
|
9
|
+
if all_loaded?
|
10
|
+
base.include(*constructors)
|
9
11
|
else
|
10
12
|
raise "Load all monads first with require 'dry/monads/all'"
|
11
13
|
end
|
12
14
|
end
|
15
|
+
|
16
|
+
# Build a module with cherry-picked monads.
|
17
|
+
# It saves a bit of typing when you add multiple
|
18
|
+
# monads to one class. Not loaded monads get loaded automatically.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# require 'dry/monads'
|
22
|
+
#
|
23
|
+
# class CreateUser
|
24
|
+
# include Dry::Monads[:result, :do]
|
25
|
+
#
|
26
|
+
# def initialize(repo, send_email)
|
27
|
+
# @repo = repo
|
28
|
+
# @send_email = send_email
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def call(name)
|
32
|
+
# if @repo.user_exist?(name)
|
33
|
+
# Failure(:user_exists)
|
34
|
+
# else
|
35
|
+
# user = yield @repo.add_user(name)
|
36
|
+
# yield @send_email.(user)
|
37
|
+
# Success(user)
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# @param [Array<Symbol>] monads
|
43
|
+
# @return [Module]
|
44
|
+
# @api public
|
45
|
+
def self.[](*monads)
|
46
|
+
monads.sort!
|
47
|
+
@mixins.fetch_or_store(monads.hash) do
|
48
|
+
monads.each { |m| load_monad(m) }
|
49
|
+
mixins = monads.map { |m| registry.fetch(m) }
|
50
|
+
Module.new { include(*mixins) }.freeze
|
51
|
+
end
|
52
|
+
end
|
13
53
|
end
|
14
54
|
end
|
data/lib/dry/monads/all.rb
CHANGED
@@ -1,26 +1,9 @@
|
|
1
1
|
require 'dry/monads'
|
2
|
-
require 'dry/monads/
|
3
|
-
require 'dry/monads/lazy'
|
4
|
-
require 'dry/monads/list'
|
5
|
-
require 'dry/monads/maybe'
|
6
|
-
require 'dry/monads/result'
|
7
|
-
require 'dry/monads/result/fixed'
|
8
|
-
require 'dry/monads/task'
|
9
|
-
require 'dry/monads/try'
|
10
|
-
require 'dry/monads/validated'
|
2
|
+
require 'dry/monads/registry'
|
11
3
|
|
12
4
|
module Dry
|
13
5
|
module Monads
|
14
|
-
|
15
|
-
|
16
|
-
Lazy::Mixin::Constructors,
|
17
|
-
Maybe::Mixin::Constructors,
|
18
|
-
Result::Mixin::Constructors,
|
19
|
-
Task::Mixin::Constructors,
|
20
|
-
Try::Mixin::Constructors,
|
21
|
-
Validated::Mixin::Constructors,
|
22
|
-
].freeze
|
23
|
-
|
24
|
-
extend(*CONSTRUCTORS)
|
6
|
+
known_monads.each { |m| load_monad(m) }
|
7
|
+
extend(*constructors)
|
25
8
|
end
|
26
9
|
end
|
data/lib/dry/monads/do/all.rb
CHANGED
@@ -77,6 +77,11 @@ module Dry
|
|
77
77
|
|
78
78
|
base.prepend(wrappers[base])
|
79
79
|
end
|
80
|
+
|
81
|
+
def included(base)
|
82
|
+
super
|
83
|
+
Dry::Monads::Do::All.included(base)
|
84
|
+
end
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
@@ -101,5 +106,8 @@ module Dry
|
|
101
106
|
end
|
102
107
|
end
|
103
108
|
end
|
109
|
+
|
110
|
+
require 'dry/monads/registry'
|
111
|
+
register_mixin(:do, Do::All)
|
104
112
|
end
|
105
113
|
end
|
data/lib/dry/monads/lazy.rb
CHANGED
data/lib/dry/monads/list.rb
CHANGED
@@ -308,6 +308,39 @@ module Dry
|
|
308
308
|
self
|
309
309
|
end
|
310
310
|
|
311
|
+
# Iterates over the list and collects Some values.
|
312
|
+
#
|
313
|
+
# @example with block syntax
|
314
|
+
# n = 20
|
315
|
+
# List[10, 5, 0].collect do |divisor|
|
316
|
+
# if divisor.zero?
|
317
|
+
# None()
|
318
|
+
# else
|
319
|
+
# Some(n / divisor)
|
320
|
+
# end
|
321
|
+
# end
|
322
|
+
# # => List[4, 2]
|
323
|
+
#
|
324
|
+
# @example without block
|
325
|
+
# List[Some(5), None(), Some(3)].collect.map { |x| x * 2 }
|
326
|
+
# # => [10, 6]
|
327
|
+
#
|
328
|
+
# @return [List]
|
329
|
+
def collect
|
330
|
+
if block_given?
|
331
|
+
collected = value.each_with_object([]) do |x, ys|
|
332
|
+
y = yield(x)
|
333
|
+
ys << y.value! if y.some?
|
334
|
+
end
|
335
|
+
|
336
|
+
List.new(collected)
|
337
|
+
else
|
338
|
+
Enumerator.new do |g|
|
339
|
+
value.each { |x| g << x.value! if x.some? }
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
311
344
|
private
|
312
345
|
|
313
346
|
def coerce(other)
|
@@ -376,6 +409,9 @@ module Dry
|
|
376
409
|
end
|
377
410
|
end
|
378
411
|
end
|
412
|
+
|
413
|
+
require 'dry/monads/registry'
|
414
|
+
register_mixin(:list, List::Mixin)
|
379
415
|
end
|
380
416
|
end
|
381
417
|
|
data/lib/dry/monads/maybe.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'concurrent/map'
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
# Common, idiomatic monads for Ruby
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
module Monads
|
8
|
+
@registry = {}
|
9
|
+
@constructors = nil
|
10
|
+
@paths = {
|
11
|
+
do: 'dry/monads/do/all',
|
12
|
+
lazy: 'dry/monads/lazy',
|
13
|
+
list: 'dry/monads/list',
|
14
|
+
maybe: 'dry/monads/maybe',
|
15
|
+
task: 'dry/monads/task',
|
16
|
+
try: 'dry/monads/try',
|
17
|
+
validated: 'dry/monads/validated',
|
18
|
+
result: [
|
19
|
+
'dry/monads/result',
|
20
|
+
'dry/monads/result/fixed'
|
21
|
+
]
|
22
|
+
}.freeze
|
23
|
+
@mixins = Concurrent::Map.new
|
24
|
+
|
25
|
+
class << self
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :registry
|
29
|
+
|
30
|
+
def registry=(registry)
|
31
|
+
@constructors = nil
|
32
|
+
@registry = registry.dup.freeze
|
33
|
+
end
|
34
|
+
protected :registry=
|
35
|
+
|
36
|
+
# @private
|
37
|
+
def register_mixin(name, mod)
|
38
|
+
if registry.key?(name)
|
39
|
+
raise ArgumentError, "#{ name.inspect } is already registered"
|
40
|
+
end
|
41
|
+
self.registry = registry.merge(name => mod)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @private
|
45
|
+
def known_monads
|
46
|
+
@paths.keys
|
47
|
+
end
|
48
|
+
|
49
|
+
# @private
|
50
|
+
def load_monad(name)
|
51
|
+
path = @paths.fetch(name) {
|
52
|
+
raise ArgumentError, "#{ name.inspect } is not a known monad"
|
53
|
+
}
|
54
|
+
Array(path).each { |p| require p }
|
55
|
+
end
|
56
|
+
|
57
|
+
# @private
|
58
|
+
def constructors
|
59
|
+
@constructors ||= registry.values.map { |m|
|
60
|
+
m::Constructors if m.const_defined?(:Constructors)
|
61
|
+
}.compact
|
62
|
+
end
|
63
|
+
|
64
|
+
# @private
|
65
|
+
def all_loaded?
|
66
|
+
registry.size == @paths.size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/dry/monads/result.rb
CHANGED
@@ -124,6 +124,8 @@ module Dry
|
|
124
124
|
include RightBiased::Left
|
125
125
|
include Dry::Equalizer(:failure)
|
126
126
|
|
127
|
+
singleton_class.send(:alias_method, :call, :new)
|
128
|
+
|
127
129
|
# Returns a constructor proc
|
128
130
|
#
|
129
131
|
# @return [Proc]
|
@@ -365,5 +367,8 @@ module Dry
|
|
365
367
|
end
|
366
368
|
end
|
367
369
|
end
|
370
|
+
|
371
|
+
require 'dry/monads/registry'
|
372
|
+
register_mixin(:result, Result::Mixin)
|
368
373
|
end
|
369
374
|
end
|
@@ -21,6 +21,7 @@ module Dry
|
|
21
21
|
def m.to_proc
|
22
22
|
@to_proc ||= method(:new).to_proc
|
23
23
|
end
|
24
|
+
m.singleton_class.send(:alias_method, :call, :new)
|
24
25
|
end
|
25
26
|
|
26
27
|
# Unwraps the underlying value
|
@@ -144,6 +145,47 @@ module Dry
|
|
144
145
|
fmap { Unit }
|
145
146
|
end
|
146
147
|
|
148
|
+
# Removes one level of monad structure by joining two values.
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# include Dry::Monads::Result::Mixin
|
152
|
+
# Success(Success(5)).flatten # => Success(5)
|
153
|
+
# Success(Failure(:not_a_number)).flatten # => Failure(:not_a_number)
|
154
|
+
# Failure(:not_a_number).flatten # => Failure(:not_a_number)
|
155
|
+
#
|
156
|
+
# @return [RightBiased::Right,RightBiased::Left]
|
157
|
+
def flatten
|
158
|
+
bind(&:itself)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Combines the wrapped value with another monadic value.
|
162
|
+
# If both values are right-sided, yields a block and passes a tuple
|
163
|
+
# of values there. If no block given, returns a tuple of values wrapped with
|
164
|
+
# a monadic structure.
|
165
|
+
#
|
166
|
+
# @example
|
167
|
+
# include Dry::Monads::Result::Mixin
|
168
|
+
#
|
169
|
+
# Success(3).and(Success(5)) # => Success([3, 5])
|
170
|
+
# Success(3).and(Failure(:not_a_number)) # => Failure(:not_a_number)
|
171
|
+
# Failure(:not_a_number).and(Success(5)) # => Failure(:not_a_number)
|
172
|
+
# Success(3).and(Success(5)) { |a, b| a + b } # => Success(8)
|
173
|
+
#
|
174
|
+
# @param mb [RightBiased::Left,RightBiased::Right]
|
175
|
+
#
|
176
|
+
# @return [RightBiased::Left,RightBiased::Right]
|
177
|
+
def and(mb)
|
178
|
+
bind do |a|
|
179
|
+
mb.fmap do |b|
|
180
|
+
if block_given?
|
181
|
+
yield([a, b])
|
182
|
+
else
|
183
|
+
[a, b]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
147
189
|
private
|
148
190
|
|
149
191
|
# @api private
|
@@ -243,7 +285,23 @@ module Dry
|
|
243
285
|
#
|
244
286
|
# @return [RightBiased::Left]
|
245
287
|
def discard
|
246
|
-
|
288
|
+
self
|
289
|
+
end
|
290
|
+
|
291
|
+
# Returns self back. It exists to keep the interface
|
292
|
+
# identical to that of {RightBiased::Right}.
|
293
|
+
#
|
294
|
+
# @return [RightBiased::Left]
|
295
|
+
def flatten
|
296
|
+
self
|
297
|
+
end
|
298
|
+
|
299
|
+
# Returns self back. It exists to keep the interface
|
300
|
+
# identical to that of {RightBiased::Right}.
|
301
|
+
#
|
302
|
+
# @return [RightBiased::Left]
|
303
|
+
def and(_)
|
304
|
+
self
|
247
305
|
end
|
248
306
|
end
|
249
307
|
end
|
data/lib/dry/monads/task.rb
CHANGED
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
new(Promise.execute(executor: executor, &block))
|
55
55
|
end
|
56
56
|
|
57
|
-
# Returns a
|
57
|
+
# Returns a completed task from the given value
|
58
58
|
#
|
59
59
|
# @overload pure(value)
|
60
60
|
# @param value [Object]
|
@@ -68,6 +68,14 @@ module Dry
|
|
68
68
|
v = Undefined.default(value, block)
|
69
69
|
new(Promise.fulfill(v))
|
70
70
|
end
|
71
|
+
|
72
|
+
# Returns a failed task from the given exception
|
73
|
+
#
|
74
|
+
# @param exc [Exception]
|
75
|
+
# @return [Task]
|
76
|
+
def failed(exc)
|
77
|
+
new(Promise.reject(exc))
|
78
|
+
end
|
71
79
|
end
|
72
80
|
|
73
81
|
include ConversionStubs[:to_maybe, :to_result]
|
@@ -299,6 +307,7 @@ module Dry
|
|
299
307
|
end
|
300
308
|
end
|
301
309
|
|
302
|
-
|
310
|
+
require 'dry/monads/registry'
|
311
|
+
register_mixin(:task, Task::Mixin)
|
303
312
|
end
|
304
313
|
end
|
data/lib/dry/monads/try.rb
CHANGED
@@ -168,6 +168,8 @@ module Dry
|
|
168
168
|
include Dry::Equalizer(:exception)
|
169
169
|
include RightBiased::Left
|
170
170
|
|
171
|
+
singleton_class.send(:alias_method, :call, :new)
|
172
|
+
|
171
173
|
# @param exception [Exception]
|
172
174
|
def initialize(exception)
|
173
175
|
@exception = exception
|
@@ -273,6 +275,7 @@ module Dry
|
|
273
275
|
end
|
274
276
|
end
|
275
277
|
|
276
|
-
|
278
|
+
require 'dry/monads/registry'
|
279
|
+
register_mixin(:try, Try::Mixin)
|
277
280
|
end
|
278
281
|
end
|
data/lib/dry/monads/validated.rb
CHANGED
data/lib/dry/monads/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-monads
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Shilnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-equalizer
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- lib/dry/monads/lazy.rb
|
148
148
|
- lib/dry/monads/list.rb
|
149
149
|
- lib/dry/monads/maybe.rb
|
150
|
+
- lib/dry/monads/registry.rb
|
150
151
|
- lib/dry/monads/result.rb
|
151
152
|
- lib/dry/monads/result/fixed.rb
|
152
153
|
- lib/dry/monads/right_biased.rb
|
@@ -173,15 +174,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
173
174
|
requirements:
|
174
175
|
- - ">="
|
175
176
|
- !ruby/object:Gem::Version
|
176
|
-
version: 2.
|
177
|
+
version: 2.3.0
|
177
178
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
179
|
requirements:
|
179
180
|
- - ">="
|
180
181
|
- !ruby/object:Gem::Version
|
181
182
|
version: '0'
|
182
183
|
requirements: []
|
183
|
-
|
184
|
-
rubygems_version: 2.7.3
|
184
|
+
rubygems_version: 3.0.1
|
185
185
|
signing_key:
|
186
186
|
specification_version: 4
|
187
187
|
summary: Common monads for Ruby.
|