dry-monads 1.3.2 → 1.4.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +157 -73
  3. data/LICENSE +1 -1
  4. data/README.md +18 -38
  5. data/dry-monads.gemspec +32 -30
  6. data/lib/dry-monads.rb +3 -1
  7. data/lib/dry/monads.rb +4 -2
  8. data/lib/dry/monads/all.rb +4 -2
  9. data/lib/dry/monads/constants.rb +1 -1
  10. data/lib/dry/monads/conversion_stubs.rb +2 -0
  11. data/lib/dry/monads/curry.rb +2 -0
  12. data/lib/dry/monads/do.rb +55 -17
  13. data/lib/dry/monads/do/all.rb +39 -17
  14. data/lib/dry/monads/do/mixin.rb +2 -0
  15. data/lib/dry/monads/either.rb +9 -7
  16. data/lib/dry/monads/errors.rb +8 -3
  17. data/lib/dry/monads/lazy.rb +19 -6
  18. data/lib/dry/monads/list.rb +31 -30
  19. data/lib/dry/monads/maybe.rb +90 -19
  20. data/lib/dry/monads/registry.rb +15 -12
  21. data/lib/dry/monads/result.rb +42 -15
  22. data/lib/dry/monads/result/fixed.rb +35 -24
  23. data/lib/dry/monads/right_biased.rb +45 -24
  24. data/lib/dry/monads/task.rb +25 -22
  25. data/lib/dry/monads/transformer.rb +4 -1
  26. data/lib/dry/monads/traverse.rb +9 -1
  27. data/lib/dry/monads/try.rb +51 -13
  28. data/lib/dry/monads/unit.rb +6 -2
  29. data/lib/dry/monads/validated.rb +27 -20
  30. data/lib/dry/monads/version.rb +3 -1
  31. data/lib/json/add/dry/monads/maybe.rb +4 -3
  32. metadata +27 -75
  33. data/.codeclimate.yml +0 -12
  34. data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
  35. data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -34
  36. data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
  37. data/.github/workflows/ci.yml +0 -74
  38. data/.github/workflows/docsite.yml +0 -34
  39. data/.github/workflows/sync_configs.yml +0 -34
  40. data/.gitignore +0 -10
  41. data/.rspec +0 -4
  42. data/.rubocop.yml +0 -89
  43. data/.yardopts +0 -4
  44. data/CODE_OF_CONDUCT.md +0 -13
  45. data/CONTRIBUTING.md +0 -29
  46. data/Gemfile +0 -23
  47. data/Rakefile +0 -6
  48. data/bin/console +0 -16
  49. data/bin/setup +0 -7
  50. data/docsite/source/case-equality.html.md +0 -42
  51. data/docsite/source/do-notation.html.md +0 -207
  52. data/docsite/source/getting-started.html.md +0 -142
  53. data/docsite/source/index.html.md +0 -179
  54. data/docsite/source/list.html.md +0 -87
  55. data/docsite/source/maybe.html.md +0 -146
  56. data/docsite/source/pattern-matching.html.md +0 -68
  57. data/docsite/source/result.html.md +0 -190
  58. data/docsite/source/task.html.md +0 -126
  59. data/docsite/source/tracing-failures.html.md +0 -32
  60. data/docsite/source/try.html.md +0 -76
  61. data/docsite/source/unit.html.md +0 -36
  62. data/docsite/source/validated.html.md +0 -88
  63. data/log/.gitkeep +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Monads
3
5
  # Advanced tranformations.
@@ -25,7 +27,8 @@ module Dry
25
27
  # Lifts a block/proc over the 3-level nested structure.
26
28
  #
27
29
  # @example
28
- # List[Right(Some(1)), Left(Some(1))].fmap3 { |x| x + 1 } # => List[Right(Some(2)), Left(Some(1))]
30
+ # List[Right(Some(1)), Left(Some(1))].fmap3 { |x| x + 1 }
31
+ # # => List[Right(Some(2)), Left(Some(1))]
29
32
  # Right(None).fmap3 { |x| x + 1 } # => Right(None)
30
33
  #
31
34
  # @param args [Array<Object>] arguments will be passed to the block or the proc
@@ -1,4 +1,9 @@
1
- require 'dry/monads/validated'
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Naming/ConstantName
4
+ # rubocop:disable Style/MutableConstant
5
+
6
+ require "dry/monads/validated"
2
7
 
3
8
  module Dry
4
9
  module Monads
@@ -18,3 +23,6 @@ module Dry
18
23
  Traverse.freeze
19
24
  end
20
25
  end
26
+
27
+ # rubocop:enable Style/MutableConstant
28
+ # rubocop:enable Naming/ConstantName
@@ -1,8 +1,10 @@
1
- require 'dry/equalizer'
2
- require 'dry/core/deprecations'
1
+ # frozen_string_literal: true
3
2
 
4
- require 'dry/monads/right_biased'
5
- require 'dry/monads/conversion_stubs'
3
+ require "dry/core/equalizer"
4
+ require "dry/core/deprecations"
5
+
6
+ require "dry/monads/right_biased"
7
+ require "dry/monads/conversion_stubs"
6
8
 
7
9
  module Dry
8
10
  module Monads
@@ -20,7 +22,7 @@ module Dry
20
22
  attr_reader :exception
21
23
 
22
24
  class << self
23
- extend Core::Deprecations[:'dry-monads']
25
+ extend Core::Deprecations[:"dry-monads"]
24
26
 
25
27
  # Invokes a callable and if successful stores the result in the
26
28
  # {Try::Value} type, but if one of the specified exceptions was raised it stores
@@ -70,7 +72,8 @@ module Dry
70
72
  # @param exceptions [Array<Exception>]
71
73
  # @return [Try::Value,Try::Error]
72
74
  def [](*exceptions, &block)
73
- raise ArgumentError, 'At least one exception type required' if exceptions.empty?
75
+ raise ArgumentError, "At least one exception type required" if exceptions.empty?
76
+
74
77
  run(exceptions, block)
75
78
  end
76
79
  end
@@ -89,7 +92,7 @@ module Dry
89
92
 
90
93
  # Returns self.
91
94
  #
92
- # @return [Maybe::Some, Maybe::None]
95
+ # @return [Try::Value, Try::Error]
93
96
  def to_monad
94
97
  self
95
98
  end
@@ -107,6 +110,8 @@ module Dry
107
110
  # @param exceptions [Array<Exception>] list of exceptions to be rescued
108
111
  # @param value [Object] the value to be stored in the monad
109
112
  def initialize(exceptions, value)
113
+ super()
114
+
110
115
  @catchable = exceptions
111
116
  @value = value
112
117
  end
@@ -157,12 +162,21 @@ module Dry
157
162
  # @return [String]
158
163
  def to_s
159
164
  if Unit.equal?(@value)
160
- 'Try::Value()'
165
+ "Try::Value()"
161
166
  else
162
167
  "Try::Value(#{@value.inspect})"
163
168
  end
164
169
  end
165
170
  alias_method :inspect, :to_s
171
+
172
+ # Ignores values and returns self, see {Try::Error#recover}
173
+ #
174
+ # @param errors [Class] List of Exception subclasses
175
+ #
176
+ # @return [Try::Value]
177
+ def recover(*_errors)
178
+ self
179
+ end
166
180
  end
167
181
 
168
182
  # Represents a result of a failed execution.
@@ -176,12 +190,14 @@ module Dry
176
190
 
177
191
  # @param exception [Exception]
178
192
  def initialize(exception)
193
+ super()
194
+
179
195
  @exception = exception
180
196
  end
181
197
 
182
198
  # @return [String]
183
199
  def to_s
184
- "Try::Error(#{ exception.class }: #{ exception.message })"
200
+ "Try::Error(#{exception.class}: #{exception.message})"
185
201
  end
186
202
  alias_method :inspect, :to_s
187
203
 
@@ -208,6 +224,26 @@ module Dry
208
224
  def ===(other)
209
225
  Error === other && exception === other.exception
210
226
  end
227
+
228
+ # Acts in a similar way to `rescue`. It checks if
229
+ # {exception} is one of {errors} and yields the block if so.
230
+ #
231
+ # @param errors [Class] List of Exception subclasses
232
+ #
233
+ # @return [Try::Value]
234
+ def recover(*errors)
235
+ if errors.empty?
236
+ classes = DEFAULT_EXCEPTIONS
237
+ else
238
+ classes = errors
239
+ end
240
+
241
+ if classes.any? { |c| c === exception }
242
+ Value.new([exception.class], yield(exception))
243
+ else
244
+ self
245
+ end
246
+ end
211
247
  end
212
248
 
213
249
  # A module that can be included for easier access to Try monads.
@@ -258,8 +294,9 @@ module Dry
258
294
  #
259
295
  def Value(value = Undefined, exceptions = DEFAULT_EXCEPTIONS, &block)
260
296
  v = Undefined.default(value, block)
261
- raise ArgumentError, 'No value given' if !value.nil? && v.nil?
262
- Value.new(exceptions, v)
297
+ raise ArgumentError, "No value given" if !value.nil? && v.nil?
298
+
299
+ Try::Value.new(exceptions, v)
263
300
  end
264
301
 
265
302
  # Error constructor
@@ -274,13 +311,14 @@ module Dry
274
311
  #
275
312
  def Error(error = Undefined, &block)
276
313
  v = Undefined.default(error, block)
277
- raise ArgumentError, 'No value given' if v.nil?
314
+ raise ArgumentError, "No value given" if v.nil?
315
+
278
316
  Try::Error.new(v)
279
317
  end
280
318
  end
281
319
  end
282
320
 
283
- require 'dry/monads/registry'
321
+ require "dry/monads/registry"
284
322
  register_mixin(:try, Try::Mixin)
285
323
  end
286
324
  end
@@ -20,11 +20,15 @@ module Dry
20
20
  #
21
21
  Unit = Object.new.tap do |unit|
22
22
  def unit.to_s
23
- 'Unit'
23
+ "Unit"
24
24
  end
25
25
 
26
26
  def unit.inspect
27
- 'Unit'
27
+ "Unit"
28
+ end
29
+
30
+ def unit.deconstruct
31
+ EMPTY_ARRAY
28
32
  end
29
33
  end
30
34
  end
@@ -1,6 +1,8 @@
1
- require 'dry/monads/conversion_stubs'
2
- require 'dry/monads/constants'
3
- require 'dry/monads/right_biased'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads/conversion_stubs"
4
+ require "dry/monads/constants"
5
+ require "dry/monads/right_biased"
4
6
 
5
7
  module Dry
6
8
  module Monads
@@ -49,7 +51,8 @@ module Dry
49
51
  #
50
52
  def bind(*)
51
53
  # See https://typelevel.org/cats/datatypes/validated.html for details on why
52
- raise NotImplementedError, "Validated is not a monad because it would violate the monad laws"
54
+ raise NotImplementedError,
55
+ "Validated is not a monad because it would violate the monad laws"
53
56
  end
54
57
 
55
58
  # Valid result
@@ -58,6 +61,8 @@ module Dry
58
61
  include Dry::Equalizer(:value!)
59
62
 
60
63
  def initialize(value)
64
+ super()
65
+
61
66
  @value = value
62
67
  end
63
68
 
@@ -84,9 +89,8 @@ module Dry
84
89
  # @yieldreturn [Validated::Valid,Validated::Invalid]
85
90
  # @return [Validated::Valid,Validated::Invalid]
86
91
  #
87
- # @return [Validated::Valid]
88
- def apply(val = Undefined)
89
- Undefined.default(val) { yield }.fmap(Curry.(value!))
92
+ def apply(val = Undefined, &block)
93
+ Undefined.default(val, &block).fmap(Curry.(value!))
90
94
  end
91
95
 
92
96
  # Lifts a block/proc over Valid
@@ -131,7 +135,7 @@ module Dry
131
135
  # @param other [Object]
132
136
  # @return [Boolean]
133
137
  def ===(other)
134
- self.class == other.class && value! === other.value!
138
+ other.instance_of?(self.class) && value! === other.value!
135
139
  end
136
140
  end
137
141
 
@@ -152,6 +156,8 @@ module Dry
152
156
  include Dry::Equalizer(:error)
153
157
 
154
158
  def initialize(error, trace = RightBiased::Left.trace_caller)
159
+ super()
160
+
155
161
  @error = error
156
162
  @trace = trace
157
163
  end
@@ -166,11 +172,11 @@ module Dry
166
172
  # @yieldreturn [Validated::Valid,Validated::Invalid]
167
173
  # @return [Validated::Invalid]
168
174
  #
169
- def apply(val = Undefined)
170
- Undefined.
171
- default(val) { yield }.
172
- alt_map { |v| @error + v }.
173
- fmap { return self }
175
+ def apply(val = Undefined, &block)
176
+ Undefined
177
+ .default(val, &block)
178
+ .alt_map { |v| @error + v }
179
+ .fmap { return self }
174
180
  end
175
181
 
176
182
  # Lifts a block/proc over Invalid
@@ -211,21 +217,20 @@ module Dry
211
217
 
212
218
  # @return [String]
213
219
  def inspect
214
- "Invalid(#{ @error.inspect })"
220
+ "Invalid(#{@error.inspect})"
215
221
  end
216
222
  alias_method :to_s, :inspect
217
223
 
218
224
  # @param other [Object]
219
225
  # @return [Boolean]
220
226
  def ===(other)
221
- self.class == other.class && error === other.error
227
+ other.instance_of?(self.class) && error === other.error
222
228
  end
223
229
  end
224
230
 
225
231
  # Mixin with Validated constructors
226
232
  #
227
233
  module Mixin
228
-
229
234
  # Successful validation result
230
235
  # @see Dry::Monads::Validated::Valid
231
236
  Valid = Valid
@@ -249,7 +254,8 @@ module Dry
249
254
  #
250
255
  def Valid(value = Undefined, &block)
251
256
  v = Undefined.default(value, block)
252
- raise ArgumentError, 'No value given' if !value.nil? && v.nil?
257
+ raise ArgumentError, "No value given" if !value.nil? && v.nil?
258
+
253
259
  Valid.new(v)
254
260
  end
255
261
 
@@ -265,7 +271,8 @@ module Dry
265
271
  #
266
272
  def Invalid(value = Undefined, &block)
267
273
  v = Undefined.default(value, block)
268
- raise ArgumentError, 'No value given' if !value.nil? && v.nil?
274
+ raise ArgumentError, "No value given" if !value.nil? && v.nil?
275
+
269
276
  Invalid.new(v, RightBiased::Left.trace_caller)
270
277
  end
271
278
  end
@@ -294,14 +301,14 @@ module Dry
294
301
  class Failure < Result
295
302
  # Transforms to Validated
296
303
  #
297
- # @return [Validated::Valid]
304
+ # @return [Validated::Invalid]
298
305
  def to_validated
299
306
  Validated::Invalid.new(failure, trace)
300
307
  end
301
308
  end
302
309
  end
303
310
 
304
- require 'dry/monads/registry'
311
+ require "dry/monads/registry"
305
312
  register_mixin(:validated, Validated::Mixin)
306
313
  end
307
314
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Monads
3
5
  # Gem version
4
- VERSION = '1.3.2'.freeze
6
+ VERSION = "1.4.0"
5
7
  end
6
8
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: false
2
- require 'json' unless defined?(::JSON::JSON_LOADED) && ::JSON::JSON_LOADED
3
2
 
4
- require 'dry/monads'
3
+ require "json" unless defined?(::JSON::JSON_LOADED) && ::JSON::JSON_LOADED
4
+
5
+ require "dry/monads"
5
6
 
6
7
  # Inspired by standard library implementation
7
8
  # for Time serialization/deserialization see (json/lib/json/add/time.rb)
@@ -11,7 +12,7 @@ module Dry
11
12
  class Maybe
12
13
  # Deserializes JSON string by using Dry::Monads::Maybe#lift method
13
14
  def self.json_create(serialized)
14
- coerce(serialized.fetch('value'))
15
+ coerce(serialized.fetch("value"))
15
16
  end
16
17
 
17
18
  # Returns a hash, that will be turned into a JSON object and represent this
metadata CHANGED
@@ -1,63 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-monads
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shilnikov
8
- autorequire:
9
- bindir: exe
8
+ autorequire:
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-30 00:00:00.000000000 Z
11
+ date: 2021-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: dry-equalizer
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: dry-core
14
+ name: concurrent-ruby
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - "~>"
32
18
  - !ruby/object:Gem::Version
33
- version: '0.4'
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 0.4.4
19
+ version: '1.0'
37
20
  type: :runtime
38
21
  prerelease: false
39
22
  version_requirements: !ruby/object:Gem::Requirement
40
23
  requirements:
41
24
  - - "~>"
42
25
  - !ruby/object:Gem::Version
43
- version: '0.4'
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 0.4.4
26
+ version: '1.0'
47
27
  - !ruby/object:Gem::Dependency
48
- name: concurrent-ruby
28
+ name: dry-core
49
29
  requirement: !ruby/object:Gem::Requirement
50
30
  requirements:
51
31
  - - "~>"
52
32
  - !ruby/object:Gem::Version
53
- version: '1.0'
33
+ version: '0.7'
54
34
  type: :runtime
55
35
  prerelease: false
56
36
  version_requirements: !ruby/object:Gem::Requirement
57
37
  requirements:
58
38
  - - "~>"
59
39
  - !ruby/object:Gem::Version
60
- version: '1.0'
40
+ version: '0.7'
61
41
  - !ruby/object:Gem::Dependency
62
42
  name: bundler
63
43
  requirement: !ruby/object:Gem::Requirement
@@ -73,21 +53,21 @@ dependencies:
73
53
  - !ruby/object:Gem::Version
74
54
  version: '0'
75
55
  - !ruby/object:Gem::Dependency
76
- name: rake
56
+ name: dry-types
77
57
  requirement: !ruby/object:Gem::Requirement
78
58
  requirements:
79
59
  - - ">="
80
60
  - !ruby/object:Gem::Version
81
- version: '0'
61
+ version: 0.1.2
82
62
  type: :development
83
63
  prerelease: false
84
64
  version_requirements: !ruby/object:Gem::Requirement
85
65
  requirements:
86
66
  - - ">="
87
67
  - !ruby/object:Gem::Version
88
- version: '0'
68
+ version: 0.1.2
89
69
  - !ruby/object:Gem::Dependency
90
- name: rspec
70
+ name: rake
91
71
  requirement: !ruby/object:Gem::Requirement
92
72
  requirements:
93
73
  - - ">="
@@ -101,59 +81,29 @@ dependencies:
101
81
  - !ruby/object:Gem::Version
102
82
  version: '0'
103
83
  - !ruby/object:Gem::Dependency
104
- name: dry-types
84
+ name: rspec
105
85
  requirement: !ruby/object:Gem::Requirement
106
86
  requirements:
107
87
  - - ">="
108
88
  - !ruby/object:Gem::Version
109
- version: '0.12'
89
+ version: '0'
110
90
  type: :development
111
91
  prerelease: false
112
92
  version_requirements: !ruby/object:Gem::Requirement
113
93
  requirements:
114
94
  - - ">="
115
95
  - !ruby/object:Gem::Version
116
- version: '0.12'
117
- description: Common monads for Ruby.
96
+ version: '0'
97
+ description: Common monads for Ruby
118
98
  email:
119
99
  - fg@flashgordon.ru
120
100
  executables: []
121
101
  extensions: []
122
102
  extra_rdoc_files: []
123
103
  files:
124
- - ".codeclimate.yml"
125
- - ".github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md"
126
- - ".github/ISSUE_TEMPLATE/---bug-report.md"
127
- - ".github/ISSUE_TEMPLATE/---feature-request.md"
128
- - ".github/workflows/ci.yml"
129
- - ".github/workflows/docsite.yml"
130
- - ".github/workflows/sync_configs.yml"
131
- - ".gitignore"
132
- - ".rspec"
133
- - ".rubocop.yml"
134
- - ".yardopts"
135
104
  - CHANGELOG.md
136
- - CODE_OF_CONDUCT.md
137
- - CONTRIBUTING.md
138
- - Gemfile
139
105
  - LICENSE
140
106
  - README.md
141
- - Rakefile
142
- - bin/console
143
- - bin/setup
144
- - docsite/source/case-equality.html.md
145
- - docsite/source/do-notation.html.md
146
- - docsite/source/getting-started.html.md
147
- - docsite/source/index.html.md
148
- - docsite/source/list.html.md
149
- - docsite/source/maybe.html.md
150
- - docsite/source/pattern-matching.html.md
151
- - docsite/source/result.html.md
152
- - docsite/source/task.html.md
153
- - docsite/source/tracing-failures.html.md
154
- - docsite/source/try.html.md
155
- - docsite/source/unit.html.md
156
- - docsite/source/validated.html.md
157
107
  - dry-monads.gemspec
158
108
  - lib/dry-monads.rb
159
109
  - lib/dry/monads.rb
@@ -181,13 +131,15 @@ files:
181
131
  - lib/dry/monads/validated.rb
182
132
  - lib/dry/monads/version.rb
183
133
  - lib/json/add/dry/monads/maybe.rb
184
- - log/.gitkeep
185
- homepage: https://github.com/dry-rb/dry-monads
134
+ homepage: https://dry-rb.org/gems/dry-monads
186
135
  licenses:
187
136
  - MIT
188
137
  metadata:
189
138
  allowed_push_host: https://rubygems.org
190
- post_install_message:
139
+ changelog_uri: https://github.com/dry-rb/dry-monads/blob/master/CHANGELOG.md
140
+ source_code_uri: https://github.com/dry-rb/dry-monads
141
+ bug_tracker_uri: https://github.com/dry-rb/dry-monads/issues
142
+ post_install_message:
191
143
  rdoc_options: []
192
144
  require_paths:
193
145
  - lib
@@ -195,15 +147,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
195
147
  requirements:
196
148
  - - ">="
197
149
  - !ruby/object:Gem::Version
198
- version: 2.4.0
150
+ version: 2.6.0
199
151
  required_rubygems_version: !ruby/object:Gem::Requirement
200
152
  requirements:
201
153
  - - ">="
202
154
  - !ruby/object:Gem::Version
203
155
  version: '0'
204
156
  requirements: []
205
- rubygems_version: 3.0.6
206
- signing_key:
157
+ rubygems_version: 3.2.22
158
+ signing_key:
207
159
  specification_version: 4
208
- summary: Common monads for Ruby.
160
+ summary: Common monads for Ruby
209
161
  test_files: []