dry-monads 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: []