dry-monads 1.3.5 → 1.6.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/CHANGELOG.md +161 -80
- data/LICENSE +1 -1
- data/README.md +5 -4
- data/dry-monads.gemspec +30 -30
- data/lib/dry/monads/all.rb +2 -3
- data/lib/dry/monads/constants.rb +0 -2
- data/lib/dry/monads/curry.rb +2 -2
- data/lib/dry/monads/do/all.rb +35 -18
- data/lib/dry/monads/do.rb +48 -20
- data/lib/dry/monads/errors.rb +8 -5
- data/lib/dry/monads/lazy.rb +13 -5
- data/lib/dry/monads/list.rb +27 -37
- data/lib/dry/monads/maybe.rb +85 -26
- data/lib/dry/monads/registry.rb +20 -20
- data/lib/dry/monads/result/fixed.rb +31 -24
- data/lib/dry/monads/result.rb +37 -19
- data/lib/dry/monads/right_biased.rb +38 -31
- data/lib/dry/monads/task.rb +25 -28
- data/lib/dry/monads/transformer.rb +2 -1
- data/lib/dry/monads/traverse.rb +5 -1
- data/lib/dry/monads/try.rb +45 -18
- data/lib/dry/monads/unit.rb +9 -3
- data/lib/dry/monads/validated.rb +18 -18
- data/lib/dry/monads/version.rb +1 -1
- data/lib/dry/monads.rb +25 -4
- data/lib/dry-monads.rb +1 -1
- data/lib/json/add/dry/monads/maybe.rb +5 -5
- metadata +22 -68
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/ci.yml +0 -52
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -56
- data/.gitignore +0 -10
- data/.rspec +0 -4
- data/.rubocop.yml +0 -101
- data/.yardopts +0 -4
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -19
- data/Gemfile.devtools +0 -14
- data/Rakefile +0 -8
- data/bin/.gitkeep +0 -0
- data/bin/console +0 -17
- data/bin/setup +0 -7
- data/docsite/source/case-equality.html.md +0 -42
- data/docsite/source/do-notation.html.md +0 -207
- data/docsite/source/getting-started.html.md +0 -142
- data/docsite/source/index.html.md +0 -179
- data/docsite/source/list.html.md +0 -87
- data/docsite/source/maybe.html.md +0 -146
- data/docsite/source/pattern-matching.html.md +0 -68
- data/docsite/source/result.html.md +0 -190
- data/docsite/source/task.html.md +0 -126
- data/docsite/source/tracing-failures.html.md +0 -32
- data/docsite/source/try.html.md +0 -76
- data/docsite/source/unit.html.md +0 -36
- data/docsite/source/validated.html.md +0 -88
- data/lib/dry/monads/either.rb +0 -66
- data/log/.gitkeep +0 -0
- data/project.yml +0 -2
data/lib/dry/monads/registry.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'concurrent/map'
|
4
|
-
|
5
3
|
module Dry
|
6
4
|
# Common, idiomatic monads for Ruby
|
7
5
|
#
|
@@ -9,20 +7,20 @@ module Dry
|
|
9
7
|
module Monads
|
10
8
|
@registry = {}
|
11
9
|
@constructors = nil
|
12
|
-
@
|
13
|
-
do:
|
14
|
-
lazy:
|
15
|
-
list:
|
16
|
-
maybe:
|
17
|
-
task:
|
18
|
-
try:
|
19
|
-
validated:
|
10
|
+
@constants = {
|
11
|
+
do: "Do::All",
|
12
|
+
lazy: "Lazy",
|
13
|
+
list: "List",
|
14
|
+
maybe: "Maybe",
|
15
|
+
task: "Task",
|
16
|
+
try: "Try",
|
17
|
+
validated: "Validated",
|
20
18
|
result: [
|
21
|
-
|
22
|
-
|
19
|
+
"Result",
|
20
|
+
"Result::Fixed"
|
23
21
|
]
|
24
22
|
}.freeze
|
25
|
-
@mixins = Concurrent::Map.new
|
23
|
+
@mixins = ::Concurrent::Map.new
|
26
24
|
|
27
25
|
class << self
|
28
26
|
private
|
@@ -46,27 +44,29 @@ module Dry
|
|
46
44
|
|
47
45
|
# @private
|
48
46
|
def known_monads
|
49
|
-
@
|
47
|
+
@constants.keys
|
50
48
|
end
|
51
49
|
|
52
50
|
# @private
|
53
51
|
def load_monad(name)
|
54
|
-
|
55
|
-
raise ArgumentError, "#{name.inspect} is not a known monad"
|
52
|
+
constants = @constants.fetch(name) {
|
53
|
+
raise ::ArgumentError, "#{name.inspect} is not a known monad"
|
56
54
|
}
|
57
|
-
Array(
|
55
|
+
Array(constants).each do |const_name|
|
56
|
+
const_name.split("::").reduce(Monads) { |mod, const| mod.const_get(const) }
|
57
|
+
end
|
58
58
|
end
|
59
59
|
|
60
60
|
# @private
|
61
61
|
def constructors
|
62
|
-
@constructors ||= registry.values.
|
62
|
+
@constructors ||= registry.values.filter_map { |m|
|
63
63
|
m::Constructors if m.const_defined?(:Constructors)
|
64
|
-
}
|
64
|
+
}
|
65
65
|
end
|
66
66
|
|
67
67
|
# @private
|
68
68
|
def all_loaded?
|
69
|
-
registry.size
|
69
|
+
registry.size.eql?(@constants.size)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -1,37 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
require "dry/monads/constants"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Monads
|
7
|
+
class Result
|
8
|
+
# @see Monads#Result
|
9
|
+
# @private
|
10
|
+
class Fixed < ::Module
|
11
|
+
def self.[](error, **options)
|
12
|
+
new(error, **options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(error, **_options)
|
16
|
+
super()
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
@mod = ::Module.new do
|
19
|
+
define_method(:Failure) do |value|
|
20
|
+
if error === value
|
21
|
+
Failure.new(value, RightBiased::Left.trace_caller)
|
22
|
+
else
|
23
|
+
# per https://github.com/dry-rb/dry-monads/pull/142
|
24
|
+
raise InvalidFailureTypeError.new(value)
|
25
|
+
end
|
19
26
|
end
|
20
|
-
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
def Success(value = Undefined, &block)
|
29
|
+
v = Undefined.default(value, block || Unit)
|
30
|
+
Success.new(v)
|
31
|
+
end
|
25
32
|
end
|
26
33
|
end
|
27
|
-
end
|
28
34
|
|
29
|
-
|
35
|
+
private
|
30
36
|
|
31
|
-
|
32
|
-
|
37
|
+
def included(base)
|
38
|
+
super
|
33
39
|
|
34
|
-
|
40
|
+
base.include(@mod)
|
41
|
+
end
|
35
42
|
end
|
36
43
|
end
|
37
44
|
end
|
data/lib/dry/monads/result.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry/equalizer'
|
4
|
-
|
5
|
-
require 'dry/monads/constants'
|
6
|
-
require 'dry/monads/right_biased'
|
7
|
-
require 'dry/monads/transformer'
|
8
|
-
require 'dry/monads/conversion_stubs'
|
9
|
-
require 'dry/monads/unit'
|
10
|
-
|
11
3
|
module Dry
|
12
4
|
module Monads
|
13
5
|
# Represents an operation which either succeeded or failed.
|
@@ -86,6 +78,7 @@ module Dry
|
|
86
78
|
|
87
79
|
# @param value [Object] a value of a successful operation
|
88
80
|
def initialize(value)
|
81
|
+
super()
|
89
82
|
@value = value
|
90
83
|
end
|
91
84
|
|
@@ -115,8 +108,8 @@ module Dry
|
|
115
108
|
#
|
116
109
|
# @param args [Array<Object>] arguments will be transparently passed through to #bind
|
117
110
|
# @return [Result::Success]
|
118
|
-
def fmap(
|
119
|
-
Success.new(bind(
|
111
|
+
def fmap(...)
|
112
|
+
Success.new(bind(...))
|
120
113
|
end
|
121
114
|
|
122
115
|
# Returns result of applying first function to the internal value.
|
@@ -134,7 +127,7 @@ module Dry
|
|
134
127
|
# @return [String]
|
135
128
|
def to_s
|
136
129
|
if Unit.equal?(@value)
|
137
|
-
|
130
|
+
"Success()"
|
138
131
|
else
|
139
132
|
"Success(#{@value.inspect})"
|
140
133
|
end
|
@@ -147,6 +140,13 @@ module Dry
|
|
147
140
|
def flip
|
148
141
|
Failure.new(@value, RightBiased::Left.trace_caller)
|
149
142
|
end
|
143
|
+
|
144
|
+
# Ignores values and returns self, see {Failure#alt_map}
|
145
|
+
#
|
146
|
+
# @return [Result::Success]
|
147
|
+
def alt_map(_ = nil)
|
148
|
+
self
|
149
|
+
end
|
150
150
|
end
|
151
151
|
|
152
152
|
# Represents a value of a failed operation.
|
@@ -156,7 +156,7 @@ module Dry
|
|
156
156
|
include RightBiased::Left
|
157
157
|
include Dry::Equalizer(:failure)
|
158
158
|
|
159
|
-
singleton_class.
|
159
|
+
singleton_class.alias_method(:call, :new)
|
160
160
|
|
161
161
|
# Shortcut for Failure([...])
|
162
162
|
#
|
@@ -188,6 +188,7 @@ module Dry
|
|
188
188
|
# @param value [Object] failure value
|
189
189
|
# @param trace [String] caller line
|
190
190
|
def initialize(value, trace = RightBiased::Left.trace_caller)
|
191
|
+
super()
|
191
192
|
@value = value
|
192
193
|
@trace = trace
|
193
194
|
end
|
@@ -218,7 +219,8 @@ module Dry
|
|
218
219
|
# otherwise simply returns the first argument.
|
219
220
|
#
|
220
221
|
# @example
|
221
|
-
# Dry::Monads.Failure(ArgumentError.new('error message')).or(&:message)
|
222
|
+
# Dry::Monads.Failure(ArgumentError.new('error message')).or(&:message)
|
223
|
+
# # => "error message"
|
222
224
|
#
|
223
225
|
# @param args [Array<Object>] arguments that will be passed to a block
|
224
226
|
# if one was given, otherwise the first
|
@@ -232,7 +234,8 @@ module Dry
|
|
232
234
|
end
|
233
235
|
end
|
234
236
|
|
235
|
-
# A lifted version of `#or`. Wraps the passed value or the block
|
237
|
+
# A lifted version of `#or`. Wraps the passed value or the block
|
238
|
+
# result with Result::Success.
|
236
239
|
#
|
237
240
|
# @example
|
238
241
|
# Dry::Monads.Failure.new('no value').or_fmap('value') # => Success("value")
|
@@ -240,14 +243,14 @@ module Dry
|
|
240
243
|
#
|
241
244
|
# @param args [Array<Object>] arguments will be passed to the underlying `#or` call
|
242
245
|
# @return [Result::Success] Wrapped value
|
243
|
-
def or_fmap(
|
244
|
-
Success.new(self.or(
|
246
|
+
def or_fmap(...)
|
247
|
+
Success.new(self.or(...))
|
245
248
|
end
|
246
249
|
|
247
250
|
# @return [String]
|
248
251
|
def to_s
|
249
252
|
if Unit.equal?(@value)
|
250
|
-
|
253
|
+
"Failure()"
|
251
254
|
else
|
252
255
|
"Failure(#{@value.inspect})"
|
253
256
|
end
|
@@ -287,6 +290,21 @@ module Dry
|
|
287
290
|
def either(_, g)
|
288
291
|
g.(failure)
|
289
292
|
end
|
293
|
+
|
294
|
+
# Lifts a block/proc over Failure
|
295
|
+
#
|
296
|
+
# @overload alt_map(proc)
|
297
|
+
# @param proc [#call]
|
298
|
+
# @return [Result::Failure]
|
299
|
+
#
|
300
|
+
# @overload alt_map
|
301
|
+
# @param block [Proc]
|
302
|
+
# @return [Result::Failure]
|
303
|
+
#
|
304
|
+
def alt_map(proc = Undefined, &block)
|
305
|
+
f = Undefined.default(proc, block)
|
306
|
+
self.class.new(f.(failure), RightBiased::Left.trace_caller)
|
307
|
+
end
|
290
308
|
end
|
291
309
|
|
292
310
|
# A module that can be included for easier access to Result monads.
|
@@ -448,7 +466,7 @@ module Dry
|
|
448
466
|
end
|
449
467
|
|
450
468
|
class Invalid < Validated
|
451
|
-
#
|
469
|
+
# Converts to Result::Failure
|
452
470
|
#
|
453
471
|
# @return [Result::Failure]
|
454
472
|
def to_result
|
@@ -457,7 +475,7 @@ module Dry
|
|
457
475
|
end
|
458
476
|
end
|
459
477
|
|
460
|
-
require
|
478
|
+
require "dry/monads/registry"
|
461
479
|
register_mixin(:result, Result::Mixin)
|
462
480
|
end
|
463
481
|
end
|
@@ -1,10 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry/monads/constants'
|
4
|
-
require 'dry/monads/unit'
|
5
|
-
require 'dry/monads/curry'
|
6
|
-
require 'dry/monads/errors'
|
7
|
-
|
8
3
|
module Dry
|
9
4
|
module Monads
|
10
5
|
# A common module for right-biased monads, such as Result/Either, Maybe, and Try.
|
@@ -20,7 +15,7 @@ module Dry
|
|
20
15
|
def m.to_proc
|
21
16
|
@to_proc ||= method(:new).to_proc
|
22
17
|
end
|
23
|
-
m.singleton_class.
|
18
|
+
m.singleton_class.alias_method(:call, :new)
|
24
19
|
end
|
25
20
|
|
26
21
|
# Unwraps the underlying value
|
@@ -70,8 +65,8 @@ module Dry
|
|
70
65
|
#
|
71
66
|
# @param [Array<Object>] args arguments will be transparently passed through to #bind
|
72
67
|
# @return [RightBiased::Right]
|
73
|
-
def tee(
|
74
|
-
bind(
|
68
|
+
def tee(...)
|
69
|
+
bind(...).bind { self }
|
75
70
|
end
|
76
71
|
|
77
72
|
# Abstract method for lifting a block over the monad type.
|
@@ -90,6 +85,16 @@ module Dry
|
|
90
85
|
self
|
91
86
|
end
|
92
87
|
|
88
|
+
# Ignores arguments and returns self. It exists to keep the interface
|
89
|
+
# identical to that of {RightBiased::Left}.
|
90
|
+
#
|
91
|
+
# @param _alt [RightBiased::Right, RightBiased::Left]
|
92
|
+
#
|
93
|
+
# @return [RightBiased::Right]
|
94
|
+
def |(_alt)
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
93
98
|
# A lifted version of `#or`. For {RightBiased::Right} acts in the same way as `#or`,
|
94
99
|
# that is returns itselt.
|
95
100
|
#
|
@@ -118,18 +123,18 @@ module Dry
|
|
118
123
|
# create_user.apply(name) # => Failure(:name_missing)
|
119
124
|
#
|
120
125
|
# @return [RightBiased::Left,RightBiased::Right]
|
121
|
-
def apply(val = Undefined)
|
126
|
+
def apply(val = Undefined, &block)
|
122
127
|
unless @value.respond_to?(:call)
|
123
128
|
raise TypeError, "Cannot apply #{val.inspect} to #{@value.inspect}"
|
124
129
|
end
|
125
130
|
|
126
|
-
Undefined.default(val)
|
131
|
+
Undefined.default(val, &block).fmap { curry.(_1) }
|
127
132
|
end
|
128
133
|
|
129
134
|
# @param other [Object]
|
130
135
|
# @return [Boolean]
|
131
136
|
def ===(other)
|
132
|
-
self.class
|
137
|
+
other.instance_of?(self.class) && value! === other.value!
|
133
138
|
end
|
134
139
|
|
135
140
|
# Maps the value to Dry::Monads::Unit, useful when you don't care
|
@@ -197,11 +202,11 @@ module Dry
|
|
197
202
|
# @api private
|
198
203
|
def deconstruct
|
199
204
|
if Unit.equal?(@value)
|
200
|
-
|
201
|
-
elsif
|
202
|
-
@value
|
203
|
-
else
|
205
|
+
EMPTY_ARRAY
|
206
|
+
elsif !@value.is_a?(::Array)
|
204
207
|
[@value]
|
208
|
+
else
|
209
|
+
@value
|
205
210
|
end
|
206
211
|
end
|
207
212
|
|
@@ -226,19 +231,12 @@ module Dry
|
|
226
231
|
|
227
232
|
private
|
228
233
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
[[value], EMPTY_HASH]
|
236
|
-
end
|
237
|
-
end
|
238
|
-
else
|
239
|
-
# @api private
|
240
|
-
def destructure(*args, **kwargs)
|
241
|
-
[args, kwargs]
|
234
|
+
# @api private
|
235
|
+
def destructure(value)
|
236
|
+
if value.is_a?(::Hash)
|
237
|
+
[EMPTY_ARRAY, value]
|
238
|
+
else
|
239
|
+
[[value], EMPTY_HASH]
|
242
240
|
end
|
243
241
|
end
|
244
242
|
|
@@ -255,7 +253,7 @@ module Dry
|
|
255
253
|
# @private
|
256
254
|
# @return [String] Caller location
|
257
255
|
def self.trace_caller
|
258
|
-
caller_locations(2,
|
256
|
+
caller_locations(2, 1)[0].to_s
|
259
257
|
end
|
260
258
|
|
261
259
|
# Raises an error on accessing internal value
|
@@ -299,11 +297,20 @@ module Dry
|
|
299
297
|
raise NotImplementedError
|
300
298
|
end
|
301
299
|
|
300
|
+
# Returns the passed value. Works in pair with {RightBiased::Right#|}.
|
301
|
+
#
|
302
|
+
# @param alt [RightBiased::Right, RightBiased::Left]
|
303
|
+
#
|
304
|
+
# @return [RightBiased::Right, RightBiased::Left]
|
305
|
+
def |(alt)
|
306
|
+
self.or(alt)
|
307
|
+
end
|
308
|
+
|
302
309
|
# A lifted version of `#or`. This is basically `#or` + `#fmap`.
|
303
310
|
#
|
304
311
|
# @example
|
305
|
-
# Dry::Monads.None.
|
306
|
-
# Dry::Monads.None.
|
312
|
+
# Dry::Monads.None.or_fmap('no value') # => Some("no value")
|
313
|
+
# Dry::Monads.None.or_fmap { Time.now } # => Some(current time)
|
307
314
|
#
|
308
315
|
# @return [RightBiased::Left, RightBiased::Right]
|
309
316
|
def or_fmap(*)
|
data/lib/dry/monads/task.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
5
|
-
require 'dry/monads/unit'
|
6
|
-
require 'dry/monads/curry'
|
7
|
-
require 'dry/monads/conversion_stubs'
|
3
|
+
require "concurrent/promise"
|
8
4
|
|
9
5
|
module Dry
|
10
6
|
module Monads
|
@@ -15,7 +11,7 @@ module Dry
|
|
15
11
|
# @api public
|
16
12
|
class Task
|
17
13
|
# @api private
|
18
|
-
class Promise < Concurrent::Promise
|
14
|
+
class Promise < ::Concurrent::Promise
|
19
15
|
public :on_fulfill, :on_reject
|
20
16
|
end
|
21
17
|
private_constant :Promise
|
@@ -48,9 +44,11 @@ module Dry
|
|
48
44
|
# @example using a predefined executor
|
49
45
|
# Task[:fast] { do_quick_task }
|
50
46
|
#
|
51
|
-
# @param executor [Concurrent::AbstractExecutorService,Symbol]
|
52
|
-
#
|
53
|
-
#
|
47
|
+
# @param executor [Concurrent::AbstractExecutorService,Symbol]
|
48
|
+
# Either an executor instance
|
49
|
+
# or a name of predefined global
|
50
|
+
# from concurrent-ruby
|
51
|
+
#
|
54
52
|
# @return [Task]
|
55
53
|
def [](executor, &block)
|
56
54
|
new(Promise.execute(executor: executor, &block))
|
@@ -81,6 +79,7 @@ module Dry
|
|
81
79
|
end
|
82
80
|
|
83
81
|
include ConversionStubs[:to_maybe, :to_result]
|
82
|
+
extend ::Dry::Core::Deprecations[:"dry-monads"]
|
84
83
|
|
85
84
|
# @api private
|
86
85
|
attr_reader :promise
|
@@ -122,23 +121,23 @@ module Dry
|
|
122
121
|
# and returns another task
|
123
122
|
# @return [Task]
|
124
123
|
def bind(&block)
|
125
|
-
self.class.new(promise.flat_map {
|
124
|
+
self.class.new(promise.flat_map { block.(_1).promise })
|
126
125
|
end
|
127
|
-
|
126
|
+
deprecate :then, :bind
|
128
127
|
|
129
128
|
# @return [String]
|
130
129
|
def to_s
|
131
130
|
state = case promise.state
|
132
131
|
when :fulfilled
|
133
132
|
if Unit.equal?(value!)
|
134
|
-
|
133
|
+
"value=()"
|
135
134
|
else
|
136
135
|
"value=#{value!.inspect}"
|
137
136
|
end
|
138
137
|
when :rejected
|
139
138
|
"error=#{promise.reason.inspect}"
|
140
139
|
else
|
141
|
-
|
140
|
+
"?"
|
142
141
|
end
|
143
142
|
|
144
143
|
"Task(#{state})"
|
@@ -164,16 +163,14 @@ module Dry
|
|
164
163
|
)
|
165
164
|
|
166
165
|
promise.on_error do |v|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
child.on_reject(e)
|
174
|
-
end
|
166
|
+
inner = block.(v).promise
|
167
|
+
inner.execute
|
168
|
+
inner.on_success { child.on_fulfill(_1) }
|
169
|
+
inner.on_error { child.on_reject(_1) }
|
170
|
+
rescue StandardError => e
|
171
|
+
child.on_reject(e)
|
175
172
|
end
|
176
|
-
promise.on_success {
|
173
|
+
promise.on_success { child.on_fulfill(_1) }
|
177
174
|
|
178
175
|
self.class.new(child)
|
179
176
|
end
|
@@ -236,9 +233,9 @@ module Dry
|
|
236
233
|
#
|
237
234
|
# @param val [Task]
|
238
235
|
# @return [Task]
|
239
|
-
def apply(val = Undefined)
|
240
|
-
arg = Undefined.default(val)
|
241
|
-
bind { |f| arg.fmap {
|
236
|
+
def apply(val = Undefined, &block)
|
237
|
+
arg = Undefined.default(val, &block)
|
238
|
+
bind { |f| arg.fmap { curry(f).(_1) } }
|
242
239
|
end
|
243
240
|
|
244
241
|
# Maps a successful result to Unit, effectively discards it
|
@@ -267,8 +264,8 @@ module Dry
|
|
267
264
|
# @api private
|
268
265
|
def compare_promises(x, y)
|
269
266
|
x.equal?(y) ||
|
270
|
-
x.fulfilled? && y.fulfilled? && x.value == y.value ||
|
271
|
-
x.rejected? && y.rejected? && x.reason == y.reason
|
267
|
+
(x.fulfilled? && y.fulfilled? && x.value == y.value) ||
|
268
|
+
(x.rejected? && y.rejected? && x.reason == y.reason)
|
272
269
|
end
|
273
270
|
|
274
271
|
# Task constructors.
|
@@ -314,7 +311,7 @@ module Dry
|
|
314
311
|
end
|
315
312
|
end
|
316
313
|
|
317
|
-
require
|
314
|
+
require "dry/monads/registry"
|
318
315
|
register_mixin(:task, Task::Mixin)
|
319
316
|
end
|
320
317
|
end
|
@@ -27,7 +27,8 @@ module Dry
|
|
27
27
|
# Lifts a block/proc over the 3-level nested structure.
|
28
28
|
#
|
29
29
|
# @example
|
30
|
-
# List[Right(Some(1)), Left(Some(1))].fmap3 { |x| x + 1 }
|
30
|
+
# List[Right(Some(1)), Left(Some(1))].fmap3 { |x| x + 1 }
|
31
|
+
# # => List[Right(Some(2)), Left(Some(1))]
|
31
32
|
# Right(None).fmap3 { |x| x + 1 } # => Right(None)
|
32
33
|
#
|
33
34
|
# @param args [Array<Object>] arguments will be passed to the block or the proc
|
data/lib/dry/monads/traverse.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
# rubocop:disable Naming/ConstantName
|
4
|
+
# rubocop:disable Style/MutableConstant
|
4
5
|
|
5
6
|
module Dry
|
6
7
|
module Monads
|
@@ -20,3 +21,6 @@ module Dry
|
|
20
21
|
Traverse.freeze
|
21
22
|
end
|
22
23
|
end
|
24
|
+
|
25
|
+
# rubocop:enable Style/MutableConstant
|
26
|
+
# rubocop:enable Naming/ConstantName
|