dry-monads 1.4.0 → 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 +21 -0
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/dry-monads.gemspec +4 -4
- data/lib/dry/monads/all.rb +1 -2
- data/lib/dry/monads/constants.rb +0 -2
- data/lib/dry/monads/curry.rb +2 -2
- data/lib/dry/monads/do/all.rb +1 -3
- data/lib/dry/monads/do.rb +8 -14
- data/lib/dry/monads/errors.rb +3 -3
- data/lib/dry/monads/lazy.rb +0 -3
- data/lib/dry/monads/list.rb +7 -17
- data/lib/dry/monads/maybe.rb +8 -17
- data/lib/dry/monads/registry.rb +20 -20
- data/lib/dry/monads/result/fixed.rb +0 -2
- data/lib/dry/monads/result.rb +5 -13
- data/lib/dry/monads/right_biased.rb +11 -23
- data/lib/dry/monads/task.rb +10 -13
- data/lib/dry/monads/traverse.rb +0 -2
- data/lib/dry/monads/try.rb +5 -11
- data/lib/dry/monads/unit.rb +3 -1
- data/lib/dry/monads/validated.rb +1 -5
- data/lib/dry/monads/version.rb +1 -1
- data/lib/dry/monads.rb +24 -3
- data/lib/json/add/dry/monads/maybe.rb +2 -2
- metadata +25 -20
- data/lib/dry/monads/either.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ccc6809b903aa20a600330e62b86d8164da8394f2b7c63740d6708c73386578
|
4
|
+
data.tar.gz: a1c92edd9908da609bfe9048bf5ca1220d1f7e4c2cc894df9ea025e7df578625
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9286042f25cbb89f74d7159ef238cb834f7dddc74890c7d575978a14bd69d8d95aa46728c0f7dbfa81507af068cba4f3efa871eed9ec60d95da62db6f9810320
|
7
|
+
data.tar.gz: d723b367ba2014fa7bf907316dd93cff45be330329c83281a8640aaaa480a83c20e222d8d89736caf6acc6675c61927e3e54bf0ecb1b4df73ec1d5e2999f0d9a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
2
|
|
3
|
+
## 1.6.0 2022-11-04
|
4
|
+
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
|
8
|
+
- This version uses dry-core 1.0 (@flash-gordon)
|
9
|
+
|
10
|
+
[Compare v1.5.0...v1.6.0](https://github.com/dry-rb/dry-monads/compare/v1.5.0...v1.6.0)
|
11
|
+
|
12
|
+
## 1.5.0 2022-10-16
|
13
|
+
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- Use zeitwerk for auto-loading dry-monads classes (@flash-gordon)
|
18
|
+
- `Task#then` is deprecated in favor of `Task#bind` (@flash-gordon)
|
19
|
+
- Minimal Ruby version is now 2.7 (@flash-gordon)
|
20
|
+
- Either (old name of Result) was removed (@flash-gordon)
|
21
|
+
|
22
|
+
[Compare v1.4.0...v1.5.0](https://github.com/dry-rb/dry-monads/compare/v1.4.0...v1.5.0)
|
23
|
+
|
3
24
|
## 1.4.0 2021-07-20
|
4
25
|
|
5
26
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -8,10 +8,10 @@
|
|
8
8
|
# dry-monads [][chat]
|
9
9
|
|
10
10
|
[][gem]
|
11
|
-
[][actions]
|
12
12
|
[][codacy]
|
13
13
|
[][codacy]
|
14
|
-
[][inchpages]
|
15
15
|
|
16
16
|
## Links
|
17
17
|
|
@@ -22,8 +22,8 @@
|
|
22
22
|
|
23
23
|
This library officially supports the following Ruby versions:
|
24
24
|
|
25
|
-
* MRI `>= 2.
|
26
|
-
*
|
25
|
+
* MRI `>= 2.7.0`
|
26
|
+
* jruby `>= 9.3` (postponed until 2.7 is supported)
|
27
27
|
|
28
28
|
## License
|
29
29
|
|
data/dry-monads.gemspec
CHANGED
@@ -22,18 +22,18 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
24
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
25
|
-
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-monads/blob/
|
25
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md"
|
26
26
|
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-monads"
|
27
27
|
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-monads/issues"
|
28
28
|
|
29
|
-
spec.required_ruby_version = ">= 2.
|
29
|
+
spec.required_ruby_version = ">= 2.7.0"
|
30
30
|
|
31
31
|
# to update dependencies edit project.yml
|
32
32
|
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
33
|
-
spec.add_runtime_dependency "dry-core", "~> 0
|
33
|
+
spec.add_runtime_dependency "dry-core", "~> 1.0", "< 2"
|
34
|
+
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
34
35
|
|
35
36
|
spec.add_development_dependency "bundler"
|
36
|
-
spec.add_development_dependency "dry-types", ">= 0.1.2"
|
37
37
|
spec.add_development_dependency "rake"
|
38
38
|
spec.add_development_dependency "rspec"
|
39
39
|
end
|
data/lib/dry/monads/all.rb
CHANGED
data/lib/dry/monads/constants.rb
CHANGED
data/lib/dry/monads/curry.rb
CHANGED
@@ -7,8 +7,8 @@ module Dry
|
|
7
7
|
# @private
|
8
8
|
def self.call(value)
|
9
9
|
func = value.is_a?(Proc) ? value : value.method(:call)
|
10
|
-
seq_args = func.parameters.count { |type, _| type
|
11
|
-
seq_args += 1 if func.parameters.any? { |type, _| type
|
10
|
+
seq_args = func.parameters.count { |type, _| type.eql?(:req) || type.eql?(:opt) }
|
11
|
+
seq_args += 1 if func.parameters.any? { |type, _| type.eql?(:keyreq) }
|
12
12
|
|
13
13
|
if seq_args > 1
|
14
14
|
func.curry
|
data/lib/dry/monads/do/all.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/monads/do"
|
4
|
-
|
5
3
|
module Dry
|
6
4
|
module Monads
|
7
5
|
module Do
|
@@ -104,7 +102,7 @@ module Dry
|
|
104
102
|
def included(base)
|
105
103
|
super
|
106
104
|
|
107
|
-
wrappers = ::Hash.new {
|
105
|
+
wrappers = ::Hash.new { _1[_2] = ::Module.new }
|
108
106
|
tracker = MethodTracker.new(wrappers)
|
109
107
|
base.extend(tracker)
|
110
108
|
base.extend(InstanceMixin) unless base.is_a?(::Class)
|
data/lib/dry/monads/do.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/monads/list"
|
4
|
-
require "dry/monads/do/mixin"
|
5
|
-
require "dry/monads/constants"
|
6
|
-
|
7
3
|
module Dry
|
8
4
|
module Monads
|
9
5
|
# An implementation of do-notation.
|
@@ -12,8 +8,6 @@ module Dry
|
|
12
8
|
module Do
|
13
9
|
extend Mixin
|
14
10
|
|
15
|
-
DELEGATE = ::RUBY_VERSION < "2.7" ? "*" : "..."
|
16
|
-
|
17
11
|
VISIBILITY_WORD = {
|
18
12
|
public: "",
|
19
13
|
private: "private ",
|
@@ -110,7 +104,7 @@ module Dry
|
|
110
104
|
# @return [Module]
|
111
105
|
def for(*methods)
|
112
106
|
::Module.new do
|
113
|
-
singleton_class.
|
107
|
+
singleton_class.define_method(:included) do |base|
|
114
108
|
mod = ::Module.new
|
115
109
|
base.prepend(mod)
|
116
110
|
base.extend(MethodTracker.new(methods, base, mod))
|
@@ -130,13 +124,13 @@ module Dry
|
|
130
124
|
# @api private
|
131
125
|
def wrap_method(target, method, visibility)
|
132
126
|
target.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
133
|
-
#{VISIBILITY_WORD[visibility]} def #{method}(
|
134
|
-
if block_given?
|
135
|
-
super
|
136
|
-
else
|
137
|
-
Do.() { super { |*ms| Do.bind(ms) } }
|
138
|
-
end
|
139
|
-
end
|
127
|
+
#{VISIBILITY_WORD[visibility]} def #{method}(...) # private def create_acccount(...)
|
128
|
+
if block_given? # if block_given?
|
129
|
+
super # super
|
130
|
+
else # else
|
131
|
+
Do.() { super { |*ms| Do.bind(ms) } } # Do.() { super { |*ms| Do.bind(ms) } }
|
132
|
+
end # end
|
133
|
+
end # end
|
140
134
|
RUBY
|
141
135
|
end
|
142
136
|
|
data/lib/dry/monads/errors.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Dry
|
4
4
|
module Monads
|
5
5
|
# An unsuccessful result of extracting a value from a monad.
|
6
|
-
class UnwrapError < StandardError
|
6
|
+
class UnwrapError < ::StandardError
|
7
7
|
attr_reader :receiver
|
8
8
|
|
9
9
|
def initialize(receiver)
|
@@ -13,14 +13,14 @@ module Dry
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# An error thrown on returning a Failure of unknown type.
|
16
|
-
class InvalidFailureTypeError < StandardError
|
16
|
+
class InvalidFailureTypeError < ::StandardError
|
17
17
|
def initialize(failure)
|
18
18
|
super("Cannot create Failure from #{failure.inspect}, it doesn't meet the constraints")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
# Improper use of None
|
23
|
-
class ConstructorNotAppliedError < NoMethodError
|
23
|
+
class ConstructorNotAppliedError < ::NoMethodError
|
24
24
|
def initialize(method_name, constructor_name)
|
25
25
|
super(
|
26
26
|
"For calling .#{method_name} on #{constructor_name}() build a value "\
|
data/lib/dry/monads/lazy.rb
CHANGED
data/lib/dry/monads/list.rb
CHANGED
@@ -1,15 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/equalizer"
|
4
|
-
|
5
|
-
require "dry/monads/maybe"
|
6
|
-
require "dry/monads/task"
|
7
|
-
require "dry/monads/result"
|
8
|
-
require "dry/monads/try"
|
9
|
-
require "dry/monads/validated"
|
10
|
-
require "dry/monads/transformer"
|
11
|
-
require "dry/monads/curry"
|
12
|
-
|
13
3
|
module Dry
|
14
4
|
module Monads
|
15
5
|
# The List monad.
|
@@ -110,10 +100,10 @@ module Dry
|
|
110
100
|
# @return [List]
|
111
101
|
def bind(*args)
|
112
102
|
if block_given?
|
113
|
-
List.coerce(value.map {
|
103
|
+
List.coerce(value.map { yield(_1, *args) }.reduce([], &:+))
|
114
104
|
else
|
115
105
|
obj, *rest = args
|
116
|
-
List.coerce(value.map {
|
106
|
+
List.coerce(value.map { obj.(_1, *rest) }.reduce([], &:+))
|
117
107
|
end
|
118
108
|
end
|
119
109
|
|
@@ -128,10 +118,10 @@ module Dry
|
|
128
118
|
# @return [List]
|
129
119
|
def fmap(*args)
|
130
120
|
if block_given?
|
131
|
-
List.new(value.map {
|
121
|
+
List.new(value.map { yield(_1, *args) })
|
132
122
|
else
|
133
123
|
obj, *rest = args
|
134
|
-
List.new(value.map {
|
124
|
+
List.new(value.map { obj.(_1, *rest) })
|
135
125
|
end
|
136
126
|
end
|
137
127
|
|
@@ -270,7 +260,7 @@ module Dry
|
|
270
260
|
self.class.warn(
|
271
261
|
"Automatic monad inference is deprecated, pass a type explicitly "\
|
272
262
|
"or use a predefined constant, e.g. List::Result\n"\
|
273
|
-
"#{caller.find {
|
263
|
+
"#{caller.find { _1 !~ %r{(lib/dry/monads)|(gems)} }}"
|
274
264
|
)
|
275
265
|
self.class.new(value, value[0].monad)
|
276
266
|
end
|
@@ -317,7 +307,7 @@ module Dry
|
|
317
307
|
# @return [List]
|
318
308
|
def apply(list = Undefined, &block)
|
319
309
|
v = Undefined.default(list, &block)
|
320
|
-
fmap(Curry).bind { |f| v.fmap {
|
310
|
+
fmap(Curry).bind { |f| v.fmap { f.(_1) } }
|
321
311
|
end
|
322
312
|
|
323
313
|
# Returns the List monad.
|
@@ -362,7 +352,7 @@ module Dry
|
|
362
352
|
List.new(collected)
|
363
353
|
else
|
364
354
|
Enumerator.new do |g|
|
365
|
-
value.each {
|
355
|
+
value.each { g << _1.value! if _1.some? }
|
366
356
|
end
|
367
357
|
end
|
368
358
|
end
|
data/lib/dry/monads/maybe.rb
CHANGED
@@ -1,14 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/equalizer"
|
4
|
-
require "dry/core/deprecations"
|
5
|
-
require "dry/core/class_attributes"
|
6
|
-
|
7
|
-
require "dry/monads/right_biased"
|
8
|
-
require "dry/monads/transformer"
|
9
|
-
require "dry/monads/unit"
|
10
|
-
require "dry/monads/constants"
|
11
|
-
|
12
3
|
module Dry
|
13
4
|
module Monads
|
14
5
|
# Represents a value which can exist or not, i.e. it could be nil.
|
@@ -127,8 +118,8 @@ module Dry
|
|
127
118
|
# @param args [Array<Object>] arguments will be transparently passed through to #bind
|
128
119
|
# @return [Maybe::Some, Maybe::None] Wrapped result, i.e. nil will be mapped to None,
|
129
120
|
# other values will be wrapped with Some
|
130
|
-
def fmap(
|
131
|
-
next_value = bind(
|
121
|
+
def fmap(...)
|
122
|
+
next_value = bind(...)
|
132
123
|
|
133
124
|
if next_value.nil?
|
134
125
|
if self.class.warn_on_implicit_nil_coercion
|
@@ -140,7 +131,7 @@ module Dry
|
|
140
131
|
"You can opt out of these warnings with\n"\
|
141
132
|
"Dry::Monads::Maybe.warn_on_implicit_nil_coercion false",
|
142
133
|
uplevel: 0,
|
143
|
-
tag: :
|
134
|
+
tag: :"dry-monads"
|
144
135
|
)
|
145
136
|
end
|
146
137
|
Monads.None()
|
@@ -160,8 +151,8 @@ module Dry
|
|
160
151
|
# @param args [Array<Object>] arguments will be transparently passed through to #bind
|
161
152
|
# @return [Maybe::Some, Maybe::None] Wrapped result, i.e. nil will be mapped to None,
|
162
153
|
# other values will be wrapped with Some
|
163
|
-
def maybe(
|
164
|
-
Maybe.coerce(bind(
|
154
|
+
def maybe(...)
|
155
|
+
Maybe.coerce(bind(...))
|
165
156
|
end
|
166
157
|
|
167
158
|
# Accepts a block and runs it against the wrapped value.
|
@@ -201,7 +192,7 @@ module Dry
|
|
201
192
|
include RightBiased::Left
|
202
193
|
|
203
194
|
@instance = new.freeze
|
204
|
-
singleton_class.
|
195
|
+
singleton_class.attr_reader(:instance)
|
205
196
|
|
206
197
|
# @api private
|
207
198
|
def self.method_missing(m, *) # rubocop:disable Style/MissingRespondToMissing
|
@@ -255,8 +246,8 @@ module Dry
|
|
255
246
|
# @param args [Array<Object>] arguments will be passed to the underlying `#or` call
|
256
247
|
# @return [Maybe::Some, Maybe::None] Lifted `#or` result, i.e. nil will be mapped to None,
|
257
248
|
# other values will be wrapped with Some
|
258
|
-
def or_fmap(
|
259
|
-
Maybe.coerce(self.or(
|
249
|
+
def or_fmap(...)
|
250
|
+
Maybe.coerce(self.or(...))
|
260
251
|
end
|
261
252
|
|
262
253
|
# @return [String]
|
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
|
@@ -20,10 +20,8 @@ module Dry
|
|
20
20
|
if error === value
|
21
21
|
Failure.new(value, RightBiased::Left.trace_caller)
|
22
22
|
else
|
23
|
-
# rubocop:disable Style/RaiseArgs
|
24
23
|
# per https://github.com/dry-rb/dry-monads/pull/142
|
25
24
|
raise InvalidFailureTypeError.new(value)
|
26
|
-
# rubocop:enable Style/RaiseArgs
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
data/lib/dry/monads/result.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/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.
|
@@ -116,8 +108,8 @@ module Dry
|
|
116
108
|
#
|
117
109
|
# @param args [Array<Object>] arguments will be transparently passed through to #bind
|
118
110
|
# @return [Result::Success]
|
119
|
-
def fmap(
|
120
|
-
Success.new(bind(
|
111
|
+
def fmap(...)
|
112
|
+
Success.new(bind(...))
|
121
113
|
end
|
122
114
|
|
123
115
|
# Returns result of applying first function to the internal value.
|
@@ -164,7 +156,7 @@ module Dry
|
|
164
156
|
include RightBiased::Left
|
165
157
|
include Dry::Equalizer(:failure)
|
166
158
|
|
167
|
-
singleton_class.
|
159
|
+
singleton_class.alias_method(:call, :new)
|
168
160
|
|
169
161
|
# Shortcut for Failure([...])
|
170
162
|
#
|
@@ -251,8 +243,8 @@ module Dry
|
|
251
243
|
#
|
252
244
|
# @param args [Array<Object>] arguments will be passed to the underlying `#or` call
|
253
245
|
# @return [Result::Success] Wrapped value
|
254
|
-
def or_fmap(
|
255
|
-
Success.new(self.or(
|
246
|
+
def or_fmap(...)
|
247
|
+
Success.new(self.or(...))
|
256
248
|
end
|
257
249
|
|
258
250
|
# @return [String]
|
@@ -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.
|
@@ -12,7 +7,7 @@ module Dry
|
|
12
7
|
# Right part
|
13
8
|
#
|
14
9
|
# @api public
|
15
|
-
module Right
|
10
|
+
module Right
|
16
11
|
# @private
|
17
12
|
def self.included(m)
|
18
13
|
super
|
@@ -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.
|
@@ -133,7 +128,7 @@ module Dry
|
|
133
128
|
raise TypeError, "Cannot apply #{val.inspect} to #{@value.inspect}"
|
134
129
|
end
|
135
130
|
|
136
|
-
Undefined.default(val, &block).fmap {
|
131
|
+
Undefined.default(val, &block).fmap { curry.(_1) }
|
137
132
|
end
|
138
133
|
|
139
134
|
# @param other [Object]
|
@@ -236,19 +231,12 @@ module Dry
|
|
236
231
|
|
237
232
|
private
|
238
233
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
[[value], EMPTY_HASH]
|
246
|
-
end
|
247
|
-
end
|
248
|
-
else
|
249
|
-
# @api private
|
250
|
-
def destructure(*args, **kwargs)
|
251
|
-
[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]
|
252
240
|
end
|
253
241
|
end
|
254
242
|
|
data/lib/dry/monads/task.rb
CHANGED
@@ -2,10 +2,6 @@
|
|
2
2
|
|
3
3
|
require "concurrent/promise"
|
4
4
|
|
5
|
-
require "dry/monads/unit"
|
6
|
-
require "dry/monads/curry"
|
7
|
-
require "dry/monads/conversion_stubs"
|
8
|
-
|
9
5
|
module Dry
|
10
6
|
module Monads
|
11
7
|
# The Task monad represents an async computation. The implementation
|
@@ -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
|
@@ -83,6 +79,7 @@ module Dry
|
|
83
79
|
end
|
84
80
|
|
85
81
|
include ConversionStubs[:to_maybe, :to_result]
|
82
|
+
extend ::Dry::Core::Deprecations[:"dry-monads"]
|
86
83
|
|
87
84
|
# @api private
|
88
85
|
attr_reader :promise
|
@@ -124,9 +121,9 @@ module Dry
|
|
124
121
|
# and returns another task
|
125
122
|
# @return [Task]
|
126
123
|
def bind(&block)
|
127
|
-
self.class.new(promise.flat_map {
|
124
|
+
self.class.new(promise.flat_map { block.(_1).promise })
|
128
125
|
end
|
129
|
-
|
126
|
+
deprecate :then, :bind
|
130
127
|
|
131
128
|
# @return [String]
|
132
129
|
def to_s
|
@@ -168,12 +165,12 @@ module Dry
|
|
168
165
|
promise.on_error do |v|
|
169
166
|
inner = block.(v).promise
|
170
167
|
inner.execute
|
171
|
-
inner.on_success {
|
172
|
-
inner.on_error {
|
168
|
+
inner.on_success { child.on_fulfill(_1) }
|
169
|
+
inner.on_error { child.on_reject(_1) }
|
173
170
|
rescue StandardError => e
|
174
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
|
@@ -238,7 +235,7 @@ module Dry
|
|
238
235
|
# @return [Task]
|
239
236
|
def apply(val = Undefined, &block)
|
240
237
|
arg = Undefined.default(val, &block)
|
241
|
-
bind { |f| arg.fmap {
|
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.
|
data/lib/dry/monads/traverse.rb
CHANGED
data/lib/dry/monads/try.rb
CHANGED
@@ -1,11 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/equalizer"
|
4
|
-
require "dry/core/deprecations"
|
5
|
-
|
6
|
-
require "dry/monads/right_biased"
|
7
|
-
require "dry/monads/conversion_stubs"
|
8
|
-
|
9
3
|
module Dry
|
10
4
|
module Monads
|
11
5
|
# Represents a value which can be either success or a failure (an exception).
|
@@ -135,7 +129,7 @@ module Dry
|
|
135
129
|
# object and the rest of args will be passed
|
136
130
|
# to this object along with the internal value
|
137
131
|
# @return [Object, Try::Error]
|
138
|
-
def bind(
|
132
|
+
def bind(...)
|
139
133
|
super
|
140
134
|
rescue *catchable => e
|
141
135
|
Error.new(e)
|
@@ -153,8 +147,8 @@ module Dry
|
|
153
147
|
# @param args [Array<Object>] extra arguments for the block, arguments are being processes
|
154
148
|
# just as in #bind
|
155
149
|
# @return [Try::Value, Try::Error]
|
156
|
-
def fmap(
|
157
|
-
Value.new(catchable, bind_call(
|
150
|
+
def fmap(...)
|
151
|
+
Value.new(catchable, bind_call(...))
|
158
152
|
rescue *catchable => e
|
159
153
|
Error.new(e)
|
160
154
|
end
|
@@ -186,7 +180,7 @@ module Dry
|
|
186
180
|
include Dry::Equalizer(:exception)
|
187
181
|
include RightBiased::Left
|
188
182
|
|
189
|
-
singleton_class.
|
183
|
+
singleton_class.alias_method(:call, :new)
|
190
184
|
|
191
185
|
# @param exception [Exception]
|
192
186
|
def initialize(exception)
|
@@ -238,7 +232,7 @@ module Dry
|
|
238
232
|
classes = errors
|
239
233
|
end
|
240
234
|
|
241
|
-
if classes.any? {
|
235
|
+
if classes.any? { _1 === exception }
|
242
236
|
Value.new([exception.class], yield(exception))
|
243
237
|
else
|
244
238
|
self
|
data/lib/dry/monads/unit.rb
CHANGED
@@ -18,7 +18,7 @@ module Dry
|
|
18
18
|
# Maybe(Unit)
|
19
19
|
# => Some(Unit)
|
20
20
|
#
|
21
|
-
Unit = Object.new.tap do |unit|
|
21
|
+
Unit = ::Object.new.tap do |unit|
|
22
22
|
def unit.to_s
|
23
23
|
"Unit"
|
24
24
|
end
|
@@ -30,6 +30,8 @@ module Dry
|
|
30
30
|
def unit.deconstruct
|
31
31
|
EMPTY_ARRAY
|
32
32
|
end
|
33
|
+
|
34
|
+
unit.freeze
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
data/lib/dry/monads/validated.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/monads/conversion_stubs"
|
4
|
-
require "dry/monads/constants"
|
5
|
-
require "dry/monads/right_biased"
|
6
|
-
|
7
3
|
module Dry
|
8
4
|
module Monads
|
9
5
|
# Validated is similar to Result and represents an outcome of a validation.
|
@@ -175,7 +171,7 @@ module Dry
|
|
175
171
|
def apply(val = Undefined, &block)
|
176
172
|
Undefined
|
177
173
|
.default(val, &block)
|
178
|
-
.alt_map {
|
174
|
+
.alt_map { @error + _1 }
|
179
175
|
.fmap { return self }
|
180
176
|
end
|
181
177
|
|
data/lib/dry/monads/version.rb
CHANGED
data/lib/dry/monads.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "concurrent/map"
|
4
|
+
require "zeitwerk"
|
5
|
+
require "dry/core"
|
6
|
+
require "dry/monads/constants"
|
7
|
+
require "dry/monads/errors"
|
4
8
|
require "dry/monads/registry"
|
5
9
|
|
6
10
|
module Dry
|
@@ -8,6 +12,21 @@ module Dry
|
|
8
12
|
#
|
9
13
|
# @api public
|
10
14
|
module Monads
|
15
|
+
# @api private
|
16
|
+
def self.loader
|
17
|
+
@loader ||= Zeitwerk::Loader.new.tap do |loader|
|
18
|
+
root = File.expand_path("..", __dir__)
|
19
|
+
loader.tag = "dry-monads"
|
20
|
+
loader.inflector = Zeitwerk::GemInflector.new("#{root}/dry-monads.rb")
|
21
|
+
loader.push_dir(root)
|
22
|
+
loader.ignore(
|
23
|
+
"#{root}/dry-monads.rb",
|
24
|
+
"#{root}/dry/monads/{all,constants,errors,registry,version}.rb",
|
25
|
+
"#{root}/json/**/*.rb"
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
11
30
|
# @private
|
12
31
|
def self.included(base)
|
13
32
|
if all_loaded?
|
@@ -49,10 +68,12 @@ module Dry
|
|
49
68
|
def self.[](*monads)
|
50
69
|
monads.sort!
|
51
70
|
@mixins.fetch_or_store(monads.hash) do
|
52
|
-
monads.each {
|
53
|
-
mixins = monads.map {
|
71
|
+
monads.each { load_monad(_1) }
|
72
|
+
mixins = monads.map { registry.fetch(_1) }
|
54
73
|
::Module.new { include(*mixins) }.freeze
|
55
74
|
end
|
56
75
|
end
|
76
|
+
|
77
|
+
loader.setup
|
57
78
|
end
|
58
79
|
end
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Shilnikov
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -30,42 +30,48 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
33
|
+
version: '1.0'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '2'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
43
|
+
version: '1.0'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
48
|
+
name: zeitwerk
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
|
-
- - "
|
51
|
+
- - "~>"
|
46
52
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
53
|
+
version: '2.6'
|
54
|
+
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
51
57
|
requirements:
|
52
|
-
- - "
|
58
|
+
- - "~>"
|
53
59
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
60
|
+
version: '2.6'
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
62
|
+
name: bundler
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
65
|
- - ">="
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
67
|
+
version: '0'
|
62
68
|
type: :development
|
63
69
|
prerelease: false
|
64
70
|
version_requirements: !ruby/object:Gem::Requirement
|
65
71
|
requirements:
|
66
72
|
- - ">="
|
67
73
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
74
|
+
version: '0'
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: rake
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +120,6 @@ files:
|
|
114
120
|
- lib/dry/monads/do.rb
|
115
121
|
- lib/dry/monads/do/all.rb
|
116
122
|
- lib/dry/monads/do/mixin.rb
|
117
|
-
- lib/dry/monads/either.rb
|
118
123
|
- lib/dry/monads/errors.rb
|
119
124
|
- lib/dry/monads/lazy.rb
|
120
125
|
- lib/dry/monads/list.rb
|
@@ -136,10 +141,10 @@ licenses:
|
|
136
141
|
- MIT
|
137
142
|
metadata:
|
138
143
|
allowed_push_host: https://rubygems.org
|
139
|
-
changelog_uri: https://github.com/dry-rb/dry-monads/blob/
|
144
|
+
changelog_uri: https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md
|
140
145
|
source_code_uri: https://github.com/dry-rb/dry-monads
|
141
146
|
bug_tracker_uri: https://github.com/dry-rb/dry-monads/issues
|
142
|
-
post_install_message:
|
147
|
+
post_install_message:
|
143
148
|
rdoc_options: []
|
144
149
|
require_paths:
|
145
150
|
- lib
|
@@ -147,15 +152,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
152
|
requirements:
|
148
153
|
- - ">="
|
149
154
|
- !ruby/object:Gem::Version
|
150
|
-
version: 2.
|
155
|
+
version: 2.7.0
|
151
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
157
|
requirements:
|
153
158
|
- - ">="
|
154
159
|
- !ruby/object:Gem::Version
|
155
160
|
version: '0'
|
156
161
|
requirements: []
|
157
|
-
rubygems_version: 3.
|
158
|
-
signing_key:
|
162
|
+
rubygems_version: 3.1.6
|
163
|
+
signing_key:
|
159
164
|
specification_version: 4
|
160
165
|
summary: Common monads for Ruby
|
161
166
|
test_files: []
|
data/lib/dry/monads/either.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dry/core/deprecations"
|
4
|
-
|
5
|
-
Dry::Core::Deprecations.warn("Either monad was renamed to Result", tag: :"dry-monads")
|
6
|
-
|
7
|
-
require "dry/monads/result"
|
8
|
-
|
9
|
-
module Dry
|
10
|
-
module Monads
|
11
|
-
Either = Result
|
12
|
-
deprecate_constant :Either
|
13
|
-
|
14
|
-
class Result
|
15
|
-
extend ::Dry::Core::Deprecations[:"dry-monads"]
|
16
|
-
|
17
|
-
deprecate :to_either, :to_result
|
18
|
-
|
19
|
-
Right = Success
|
20
|
-
Left = Failure
|
21
|
-
|
22
|
-
deprecate_constant :Right
|
23
|
-
deprecate_constant :Left
|
24
|
-
|
25
|
-
module Mixin
|
26
|
-
module Constructors
|
27
|
-
extend Dry::Core::Deprecations[:"dry-monads"]
|
28
|
-
|
29
|
-
Right = Success
|
30
|
-
Left = Failure
|
31
|
-
deprecate_constant :Right
|
32
|
-
deprecate_constant :Left
|
33
|
-
|
34
|
-
deprecate :Right, :Success
|
35
|
-
deprecate :Left, :Failure
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class Success
|
40
|
-
deprecate :left?, :failure?
|
41
|
-
deprecate :right?, :success?
|
42
|
-
end
|
43
|
-
|
44
|
-
class Failure
|
45
|
-
deprecate :left?, :failure?
|
46
|
-
deprecate :right?, :success?
|
47
|
-
|
48
|
-
deprecate :left, :failure
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class Try
|
53
|
-
class Value
|
54
|
-
extend Dry::Core::Deprecations[:"dry-monads"]
|
55
|
-
|
56
|
-
deprecate :to_either, :to_result
|
57
|
-
end
|
58
|
-
|
59
|
-
class Error
|
60
|
-
extend Dry::Core::Deprecations[:"dry-monads"]
|
61
|
-
|
62
|
-
deprecate :to_either, :to_result
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|