dry-monads 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|