kind 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -24
- data/lib/kind/maybe.rb +91 -0
- data/lib/kind/version.rb +1 -1
- data/lib/kind.rb +5 -3
- metadata +2 -2
- data/lib/kind/optional.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfe4558ce7a6bb67a5c7cb76d0ab12465ef644a909cc6f52e6c7890327db3a13
|
4
|
+
data.tar.gz: 511872fbaaf0884287c2d5c8e8e0e871ba832c828892ab9124f38cb458b6a2d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d540ca9ec1ae62b1c560c9a3791742312832c7a4bd663cc319a5d2ac4ea7ed4a47c97de5810114d2a12f930bcf824513b058eaca37c3c736c136e5060eb55e1
|
7
|
+
data.tar.gz: 3b3e80863478ca100746dfe778ea1cccf9a66d19fe4748b0f07e7c1f27e987b11bf673b35b8f797fcb21b693f69ad3692b39d2a4b8433dc302b33cf1dca15bfa
|
data/README.md
CHANGED
@@ -27,9 +27,9 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
27
27
|
- [Kind.of](#kindof)
|
28
28
|
- [Kind.is](#kindis)
|
29
29
|
- [Kind::Undefined](#kindundefined)
|
30
|
-
- [Kind::
|
31
|
-
- [Kind::
|
32
|
-
- [Kind::
|
30
|
+
- [Kind::Maybe](#kindmaybe)
|
31
|
+
- [Kind::Maybe[] and Kind::Maybe#then](#kindmaybe-and-kindmaybethen)
|
32
|
+
- [Kind::Maybe#try](#kindmaybetry)
|
33
33
|
- [Development](#development)
|
34
34
|
- [Contributing](#contributing)
|
35
35
|
- [License](#license)
|
@@ -288,15 +288,15 @@ If you are interested, check out [the tests](https://github.com/serradura/kind/b
|
|
288
288
|
|
289
289
|
[⬆️ Back to Top](#table-of-contents-)
|
290
290
|
|
291
|
-
## Kind::
|
291
|
+
## Kind::Maybe
|
292
292
|
|
293
|
-
The `Kind::
|
293
|
+
The `Kind::Maybe` is used when a series of computations (in a chain of map callings) could return `nil` or `Kind::Undefined` at any point.
|
294
294
|
|
295
295
|
```ruby
|
296
296
|
optional =
|
297
|
-
Kind::
|
298
|
-
|
299
|
-
|
297
|
+
Kind::Maybe.new(2)
|
298
|
+
.map { |value| value * 2 }
|
299
|
+
.map { |value| value * 2 }
|
300
300
|
|
301
301
|
puts optional.value # 8
|
302
302
|
puts optional.some? # true
|
@@ -309,9 +309,9 @@ puts optional.value_or { 0 } # 8
|
|
309
309
|
#################
|
310
310
|
|
311
311
|
optional =
|
312
|
-
Kind::
|
313
|
-
|
314
|
-
|
312
|
+
Kind::Maybe.new(3)
|
313
|
+
.map { nil }
|
314
|
+
.map { |value| value * 3 }
|
315
315
|
|
316
316
|
puts optional.value # nil
|
317
317
|
puts optional.some? # false
|
@@ -324,9 +324,9 @@ puts optional.value_or { 0 } # 0
|
|
324
324
|
#############################
|
325
325
|
|
326
326
|
optional =
|
327
|
-
Kind::
|
328
|
-
|
329
|
-
|
327
|
+
Kind::Maybe.new(4)
|
328
|
+
.map { Kind::Undefined }
|
329
|
+
.map { |value| value * 4 }
|
330
330
|
|
331
331
|
puts optional.value # Kind::Undefined
|
332
332
|
puts optional.some? # false
|
@@ -335,13 +335,13 @@ puts optional.value_or(1) # 1
|
|
335
335
|
puts optional.value_or { 1 } # 1
|
336
336
|
```
|
337
337
|
|
338
|
-
### Kind::
|
338
|
+
### Kind::Maybe[] and Kind::Maybe#then
|
339
339
|
|
340
|
-
You can use `Kind::
|
340
|
+
You can use `Kind::Maybe[]` (brackets) instead of the `.new` to transform values in a `Kind::Maybe`. Another alias is `.then` to the `.map` method.
|
341
341
|
|
342
342
|
```ruby
|
343
343
|
result =
|
344
|
-
Kind::
|
344
|
+
Kind::Maybe[5]
|
345
345
|
.then { |value| value * 5 }
|
346
346
|
.then { |value| value + 17 }
|
347
347
|
.value_or(0)
|
@@ -349,30 +349,36 @@ result =
|
|
349
349
|
puts result # 42
|
350
350
|
```
|
351
351
|
|
352
|
-
### Kind::
|
352
|
+
### Kind::Maybe#try
|
353
353
|
|
354
354
|
If you don't want to use a map to access the value, you could use the `#try` method to access it. So, if the value wasn't `nil` or `Kind::Undefined`, it will be returned.
|
355
355
|
|
356
356
|
```ruby
|
357
|
-
|
357
|
+
object = 'foo'
|
358
358
|
|
359
|
-
p Kind::
|
359
|
+
p Kind::Maybe[object].try(:upcase) # "FOO"
|
360
|
+
|
361
|
+
p Kind::Maybe[object].try { |value| value.upcase } # "FOO"
|
360
362
|
|
361
363
|
#############
|
362
364
|
# Nil value #
|
363
365
|
#############
|
364
366
|
|
365
|
-
|
367
|
+
object = nil
|
368
|
+
|
369
|
+
p Kind::Maybe[object].try(:upcase) # nil
|
366
370
|
|
367
|
-
p Kind::
|
371
|
+
p Kind::Maybe[object].try { |value| value.upcase } # nil
|
368
372
|
|
369
373
|
#########################
|
370
374
|
# Kind::Undefined value #
|
371
375
|
#########################
|
372
376
|
|
373
|
-
|
377
|
+
object = Kind::Undefined
|
378
|
+
|
379
|
+
p Kind::Maybe[object].try(:upcase) # nil
|
374
380
|
|
375
|
-
p Kind::
|
381
|
+
p Kind::Maybe[object].try { |value| value.upcase } # nil
|
376
382
|
```
|
377
383
|
|
378
384
|
[⬆️ Back to Top](#table-of-contents-)
|
data/lib/kind/maybe.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
module Maybe
|
5
|
+
def self.none?(value)
|
6
|
+
value == nil || value == Undefined
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.some?(value)
|
10
|
+
!none?(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.new(value)
|
14
|
+
result_type = some?(value) ? Some : None
|
15
|
+
result_type.new(value.is_a?(Result) ? value.value : value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.[](value);
|
19
|
+
new(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
class Result
|
23
|
+
attr_reader :value
|
24
|
+
|
25
|
+
def initialize(value)
|
26
|
+
@value = value
|
27
|
+
end
|
28
|
+
|
29
|
+
INVALID_DEFAULT_ARG = 'the default value must be defined as an argument or block'.freeze
|
30
|
+
|
31
|
+
def value_or(default = Undefined, &block)
|
32
|
+
return @value if some?
|
33
|
+
|
34
|
+
if default == Undefined && !block
|
35
|
+
raise ArgumentError, INVALID_DEFAULT_ARG
|
36
|
+
else
|
37
|
+
Maybe.some?(default) ? default : block.call
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def none?; end
|
42
|
+
|
43
|
+
def some?; !none?; end
|
44
|
+
|
45
|
+
def map(&fn); end
|
46
|
+
|
47
|
+
def try(method_name = Undefined, &block)
|
48
|
+
fn = method_name == Undefined ? block : Kind.of.Symbol(method_name).to_proc
|
49
|
+
|
50
|
+
if Maybe.some?(value)
|
51
|
+
result = fn.call(value)
|
52
|
+
|
53
|
+
return result if Maybe.some?(result)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private_constant :INVALID_DEFAULT_ARG
|
58
|
+
end
|
59
|
+
|
60
|
+
class None < Result
|
61
|
+
def none?; true; end
|
62
|
+
|
63
|
+
def map(&fn)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
alias_method :then, :map
|
68
|
+
end
|
69
|
+
|
70
|
+
NONE_WITH_NIL = None.new(nil)
|
71
|
+
NONE_WITH_UNDEFINED = None.new(Undefined)
|
72
|
+
|
73
|
+
class Some < Result
|
74
|
+
def none?; false; end
|
75
|
+
|
76
|
+
def map(&fn)
|
77
|
+
result = yield(@value)
|
78
|
+
|
79
|
+
return NONE_WITH_NIL if result == nil
|
80
|
+
return NONE_WITH_UNDEFINED if result == Undefined
|
81
|
+
return Some.new(result)
|
82
|
+
end
|
83
|
+
|
84
|
+
alias_method :then, :map
|
85
|
+
end
|
86
|
+
|
87
|
+
private_constant :Result, :NONE_WITH_NIL, :NONE_WITH_UNDEFINED
|
88
|
+
end
|
89
|
+
|
90
|
+
Optional = Maybe
|
91
|
+
end
|
data/lib/kind/version.rb
CHANGED
data/lib/kind.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'kind/version'
|
4
4
|
require 'kind/undefined'
|
5
|
-
require 'kind/
|
5
|
+
require 'kind/maybe'
|
6
6
|
require 'kind/error'
|
7
7
|
require 'kind/is'
|
8
8
|
require 'kind/checker'
|
@@ -101,7 +101,7 @@ module Kind
|
|
101
101
|
|
102
102
|
return Kind::Of::Callable if object == Undefined && default.nil?
|
103
103
|
|
104
|
-
callable = object
|
104
|
+
callable = object || default
|
105
105
|
|
106
106
|
return callable if callable.respond_to?(:call)
|
107
107
|
|
@@ -113,7 +113,9 @@ module Kind
|
|
113
113
|
|
114
114
|
def self.__kind; Object; end
|
115
115
|
|
116
|
-
def self.class?(value)
|
116
|
+
def self.class?(value)
|
117
|
+
Kind::Is::Callable(value)
|
118
|
+
end
|
117
119
|
|
118
120
|
def self.instance?(value);
|
119
121
|
value.respond_to?(:call)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kind
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Serradura
|
@@ -31,8 +31,8 @@ files:
|
|
31
31
|
- lib/kind/checker.rb
|
32
32
|
- lib/kind/error.rb
|
33
33
|
- lib/kind/is.rb
|
34
|
+
- lib/kind/maybe.rb
|
34
35
|
- lib/kind/of.rb
|
35
|
-
- lib/kind/optional.rb
|
36
36
|
- lib/kind/types.rb
|
37
37
|
- lib/kind/undefined.rb
|
38
38
|
- lib/kind/version.rb
|
data/lib/kind/optional.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Kind
|
4
|
-
class Optional
|
5
|
-
self.singleton_class.send(:alias_method, :[], :new)
|
6
|
-
|
7
|
-
IsNone = -> value { value == nil || value == Undefined }
|
8
|
-
|
9
|
-
attr_reader :value
|
10
|
-
|
11
|
-
def initialize(arg)
|
12
|
-
@value = arg.is_a?(Kind::Optional) ? arg.value : arg
|
13
|
-
end
|
14
|
-
|
15
|
-
INVALID_DEFAULT_ARG = 'the default value must be defined as an argument or block'.freeze
|
16
|
-
|
17
|
-
def value_or(default = Undefined, &block)
|
18
|
-
return @value if some?
|
19
|
-
|
20
|
-
if default == Undefined && !block
|
21
|
-
raise ArgumentError, INVALID_DEFAULT_ARG
|
22
|
-
else
|
23
|
-
IsNone.(default) ? block.call : default
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def none?
|
28
|
-
@none ||= IsNone.(@value)
|
29
|
-
end
|
30
|
-
|
31
|
-
def some?
|
32
|
-
!none?
|
33
|
-
end
|
34
|
-
|
35
|
-
def map(&fn)
|
36
|
-
return self if none?
|
37
|
-
|
38
|
-
self.class.new(fn.call(@value))
|
39
|
-
end
|
40
|
-
|
41
|
-
alias_method :then, :map
|
42
|
-
|
43
|
-
def try(method_name = Undefined, &block)
|
44
|
-
fn = method_name == Undefined ? block : Kind.of.Symbol(method_name).to_proc
|
45
|
-
|
46
|
-
unless IsNone.(value)
|
47
|
-
result = fn.call(value)
|
48
|
-
|
49
|
-
return result unless IsNone.(result)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
private_constant :IsNone, :INVALID_DEFAULT_ARG
|
54
|
-
end
|
55
|
-
end
|