kind 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebd68f3e676f6b030fa85da36b57a47a7f866e52373aed2b0e41315c63b0fdd0
4
- data.tar.gz: 5800122e2ed54025450eabe06bee5f9df3474c45b6ffa396c3b80dc4ad8ca566
3
+ metadata.gz: a83d36b4c1fe131567251f418b775a8366ecf2a7c0d31682f801866cb9d83a27
4
+ data.tar.gz: b9b613500675aa1ea9e10c4b5ff83a451f289aec39896aaed025c196f0212ece
5
5
  SHA512:
6
- metadata.gz: d3769fbbe39073a41961af28fde90412f30f1caab3b2129b4a91a39afb1e482310e209b1a5eea4249f09c667760f862c06cc98dc56ab7bb40854561ef75ea435
7
- data.tar.gz: 8356c7a49afe6370ecced9485acd2a663d1f17729cbbccd89dec2c1f839ad0f754778502e447c89b8a129697a891bed07af30c20df0b52a9e4d338cb4df593ed
6
+ metadata.gz: 252e2e4f3bd9bbd09ff182579d450de170688ada607dfaa30cd70748c1ac4473381c856ba1be37f74ccd1eb05d077763cbf853ea1f356c58226408108e69f4e8
7
+ data.tar.gz: f35a606761e6de74f81427a4431c711252303f78e4b0b5d11dd5e1878180112c1733fa4fef85949f3414196e387b54c672e768384f92aff9ac1c434662529834
data/README.md CHANGED
@@ -18,11 +18,14 @@ One of the goals of this project is to do simple type checking like `"some strin
18
18
  - [Required Ruby version](#required-ruby-version)
19
19
  - [Installation](#installation)
20
20
  - [Usage](#usage)
21
- - [Verifying the kind of some object](#verifying-the-kind-of-some-object)
22
- - [Verifying the kind of some class/module](#verifying-the-kind-of-some-classmodule)
21
+ - [Kind.of.\<Type\>() - Verifying the kind of some object](#kindoftype---verifying-the-kind-of-some-object)
22
+ - [Method aliases to perform a strict validation](#method-aliases-to-perform-a-strict-validation)
23
+ - [Kind.of.\<Type\>.or_nil()](#kindoftypeor_nil)
24
+ - [Kind.of.\<Type\>.instance?()](#kindoftypeinstance)
25
+ - [Kind.is.\<Type\>() - Verifying if some class/module is the expected kind.](#kindistype---verifying-if-some-classmodule-is-the-expected-kind)
23
26
  - [How to create a new type checker?](#how-to-create-a-new-type-checker)
24
27
  - [Creating/Verifiyng type checkers dynamically](#creatingverifiyng-type-checkers-dynamically)
25
- - [Registering new (custom) type checkers](#registering-new-custom-type-checkers)
28
+ - [Registering new (custom) type checker](#registering-new-custom-type-checker)
26
29
  - [What happens if a custom type checker has a namespace?](#what-happens-if-a-custom-type-checker-has-a-namespace)
27
30
  - [Type checkers](#type-checkers)
28
31
  - [Classes' type checkers](#classes-type-checkers)
@@ -31,11 +34,15 @@ One of the goals of this project is to do simple type checking like `"some strin
31
34
  - [Kind::Undefined](#kindundefined)
32
35
  - [Kind.of.\<Type\>.or_undefined()](#kindoftypeor_undefined)
33
36
  - [Kind::Maybe](#kindmaybe)
34
- - [Kind::Maybe[] and Kind::Maybe#then](#kindmaybe-and-kindmaybethen)
35
- - [Kind::Maybe#try](#kindmaybetry)
37
+ - [Replacing blocks by lambdas](#replacing-blocks-by-lambdas)
38
+ - [Kind::Maybe[] and Kind::Maybe#then method aliases](#kindmaybe-and-kindmaybethen-method-aliases)
39
+ - [Replacing blocks by lambdas](#replacing-blocks-by-lambdas-1)
40
+ - [Kind::None() and Kind::Some()](#kindnone-and-kindsome)
36
41
  - [Kind.of.Maybe()](#kindofmaybe)
37
42
  - [Kind::Optional](#kindoptional)
43
+ - [Replacing blocks by lambdas](#replacing-blocks-by-lambdas-2)
38
44
  - [Kind.of.\<Type\>.as_optional](#kindoftypeas_optional)
45
+ - [Kind::Maybe#try](#kindmaybetry)
39
46
  - [Kind::Validator (ActiveModel::Validations)](#kindvalidator-activemodelvalidations)
40
47
  - [Usage](#usage-1)
41
48
  - [Defining the default validation strategy](#defining-the-default-validation-strategy)
@@ -82,14 +89,14 @@ sum(1, 1) # 2
82
89
  sum('1', 1) # Kind::Error ("\"1\" expected to be a kind of Numeric")
83
90
  ```
84
91
 
85
- ### Verifying the kind of some object
92
+ ### Kind.of.\<Type\>() - Verifying the kind of some object
86
93
 
87
94
  By default, basic verifications are strict. So, when you perform `Kind.of.Hash(value)`, if the given value was a Hash, the value itself will be returned, but if it isn't the right type, an error will be raised.
88
95
 
89
96
  ```ruby
90
- Kind.of.Hash(nil) # **raise Kind::Error, "nil expected to be a kind of Hash"**
91
- Kind.of.Hash('') # raise Kind::Error, "'' expected to be a kind of Hash"
92
- Kind.of.Hash({a: 1}) # {a: 1}
97
+ Kind.of.Hash(nil) # **raise Kind::Error, "nil expected to be a kind of Hash"**
98
+ Kind.of.Hash('') # raise Kind::Error, "'' expected to be a kind of Hash"
99
+ Kind.of.Hash(a: 1) # {a: 1}
93
100
 
94
101
  # ---
95
102
 
@@ -99,14 +106,12 @@ Kind.of.Boolean(false) # false
99
106
  ```
100
107
 
101
108
  > **Note:** `Kind.of.<Type>` supports the to_proc protocol.
102
- > But it won't perform a strict validation, instead, it will return true
103
- > when the value has the desired kind and false if it hasn't.
109
+ > And it will perform a strict validation as expected.
104
110
 
105
111
  ```ruby
106
112
  collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
107
113
 
108
- collection
109
- .select(&Kind.of.Hash) # [{number: 1}, {number: 3}]
114
+ collection.map(&Kind.of.Hash) # Kind::Error ("number 2" expected to be a kind of Hash)
110
115
  ```
111
116
 
112
117
  When the verified value is nil, it is possible to define a default value with the same type to be returned.
@@ -123,6 +128,24 @@ Kind.of.Boolean(nil, or: true) # true
123
128
 
124
129
  > **Note:** As an alternative syntax, you can use the `Kind::Of` instead of the `Kind.of` method. e.g: `Kind::Of::Hash('')`
125
130
 
131
+ #### Method aliases to perform a strict validation
132
+
133
+ ```ruby
134
+ Kind.of.Hash[nil] # raise Kind::Error, "nil expected to be a kind of Hash"
135
+ Kind.of.Hash[''] # raise Kind::Error, "'' expected to be a kind of Hash"
136
+ Kind.of.Hash[a: 1] # {a: 1}
137
+ Kind.of.Hash['', or: {}] # {}
138
+
139
+ # or
140
+
141
+ Kind.of.Hash.instance(nil) # raise Kind::Error, "nil expected to be a kind of Hash"
142
+ Kind.of.Hash.instance('') # raise Kind::Error, "'' expected to be a kind of Hash"
143
+ Kind.of.Hash.instance(a: 1) # {a: 1}
144
+ Kind.of.Hash.instance('', or: {}) # {}
145
+ ```
146
+
147
+ ### Kind.of.\<Type\>.or_nil()
148
+
126
149
  But if you don't need a strict type verification, use the `.or_nil` method.
127
150
 
128
151
  ```ruby
@@ -135,11 +158,12 @@ Kind.of.Boolean.or_nil('') # nil
135
158
  Kind.of.Boolean.or_nil(true) # true
136
159
  ```
137
160
 
138
- And just for convenience, you can use the method `.instance?` to verify if the given object has the expected type.
161
+ ### Kind.of.\<Type\>.instance?()
162
+
163
+ Use the method `.instance?` to verify if the given object has the expected type.
139
164
 
140
165
  ```ruby
141
- Kind.of.Hash.instance?('')
142
- # false
166
+ Kind.of.Hash.instance?('') # false
143
167
 
144
168
  # ---
145
169
 
@@ -155,27 +179,19 @@ Kind.of.Boolean.instance?(false) # true
155
179
  collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
156
180
 
157
181
  collection
158
- .select(&Kind.of.Hash.instance?)
159
- .reduce(0) { |total, item| total + item.fetch(:number, 0) } # 4
182
+ .select(&Kind.of.Hash.instance?) # [{:number=>1}, {:number=>3}]
160
183
  ```
161
184
 
162
- Also, there are aliases to perform the strict type verification. e.g:
185
+ > **Note:** You can use a different syntax to perform an instance verification.
186
+ > To do this, use Kind.of.\<Type\>?()
163
187
 
164
188
  ```ruby
165
- Kind.of.Hash[nil] # raise Kind::Error, "nil expected to be a kind of Hash"
166
- Kind.of.Hash[''] # raise Kind::Error, "'' expected to be a kind of Hash"
167
- Kind.of.Hash[a: 1] # {a: 1}
168
- Kind.of.Hash['', or: {}] # {}
169
-
170
- # or
189
+ collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
171
190
 
172
- Kind.of.Hash.instance(nil) # raise Kind::Error, "nil expected to be a kind of Hash"
173
- Kind.of.Hash.instance('') # raise Kind::Error, "'' expected to be a kind of Hash"
174
- Kind.of.Hash.instance(a: 1) # {a: 1}
175
- Kind.of.Hash.instance('', or: {}) # {}
191
+ collection.select(&Kind.of.Hash?) # [{:number=>1}, {:number=>3}]
176
192
  ```
177
193
 
178
- ### Verifying the kind of some class/module
194
+ ### Kind.is.\<Type\>() - Verifying if some class/module is the expected kind.
179
195
 
180
196
  You can use `Kind.is` to verify if some class has the expected type as its ancestor.
181
197
 
@@ -262,6 +278,22 @@ Kind.of(User, {}) # Kind::Error ({} expected to be a kind of User)
262
278
  Kind.of(Hash, {}) # {}
263
279
  Kind.of(Hash, user) # Kind::Error (<User ...> expected to be a kind of Hash)
264
280
 
281
+ # ----------------------------------------- #
282
+ # Verifiyng if the value is a kind instance #
283
+ # ----------------------------------------- #
284
+
285
+ Kind.of?(Numeric, 1) # true
286
+ Kind.of?(Numeric, 1, 2.0) # true
287
+
288
+ Kind.of?(Numeric, '1') # false
289
+ Kind.of?(Numeric, 1, '2.0') # false
290
+
291
+ # Note: Kind.of?(Type) without arguments will return a
292
+ # lambda that will perform an instance verification
293
+ #
294
+ [1, '2', 3.0, '4']
295
+ .select(&Kind.of?(Numeric)) # [1, 3.0]
296
+
265
297
  # ---------------------------------- #
266
298
  # Creating type checkers dynamically #
267
299
  # ---------------------------------- #
@@ -300,7 +332,7 @@ end
300
332
  Kind.is(User, AdminUser) # true
301
333
  ```
302
334
 
303
- #### Registering new (custom) type checkers
335
+ #### Registering new (custom) type checker
304
336
 
305
337
  Use `Kind::Types.add()`. e.g:
306
338
 
@@ -491,7 +523,27 @@ puts optional.value_or(1) # 1
491
523
  puts optional.value_or { 1 } # 1
492
524
  ```
493
525
 
494
- ### Kind::Maybe[] and Kind::Maybe#then
526
+ #### Replacing blocks by lambdas
527
+
528
+ ```ruby
529
+ Add = -> params do
530
+ a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
531
+
532
+ a + b if Kind.of.Numeric?(a, b)
533
+ end
534
+
535
+ # --
536
+
537
+ Kind::Maybe.new(a: 1, b: 2).map(&Add).value_or(0) # 3
538
+
539
+ # --
540
+
541
+ Kind::Maybe.new([]).map(&Add).value_or(0) # 0
542
+ Kind::Maybe.new({}).map(&Add).value_or(0) # 0
543
+ Kind::Maybe.new(nil).map(&Add).value_or(0) # 0
544
+ ```
545
+
546
+ ### Kind::Maybe[] and Kind::Maybe#then method aliases
495
547
 
496
548
  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.
497
549
 
@@ -505,43 +557,57 @@ result =
505
557
  puts result # 42
506
558
  ```
507
559
 
508
- ### Kind::Maybe#try
509
-
510
- 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.
560
+ #### Replacing blocks by lambdas
511
561
 
512
562
  ```ruby
513
- object = 'foo'
563
+ Add = -> params do
564
+ a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
514
565
 
515
- p Kind::Maybe[object].try(:upcase) # "FOO"
566
+ a + b if Kind.of.Numeric.instance?(a, b)
567
+ end
516
568
 
517
- p Kind::Maybe[{}].try(:fetch, :number, 0) # 0
569
+ # --
518
570
 
519
- p Kind::Maybe[{number: 1}].try(:fetch, :number) # 1
571
+ Kind::Maybe[a: 1, b: 2].then(&Add).value_or(0) # 3
520
572
 
521
- p Kind::Maybe[object].try { |value| value.upcase } # "FOO"
573
+ # --
522
574
 
523
- #############
524
- # Nil value #
525
- #############
575
+ Kind::Maybe[1].then(&Add).value_or(0) # 0
576
+ Kind::Maybe['2'].then(&Add).value_or(0) # 0
577
+ Kind::Maybe[nil].then(&Add).value_or(0) # 0
578
+ ```
526
579
 
527
- object = nil
580
+ ### Kind::None() and Kind::Some()
528
581
 
529
- p Kind::Maybe[object].try(:upcase) # nil
582
+ If you need to ensure the return of `Kind::Maybe` results from your methods/lambdas,
583
+ you could use the methods `Kind::None` and `Kind::Some` to do this. e.g:
530
584
 
531
- p Kind::Maybe[object].try { |value| value.upcase } # nil
585
+ ```ruby
586
+ Add = -> params do
587
+ a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
532
588
 
533
- #########################
534
- # Kind::Undefined value #
535
- #########################
589
+ return Kind::None unless Kind.of.Numeric.instance?(a, b)
536
590
 
537
- object = Kind::Undefined
591
+ Kind::Some(a + b)
592
+ end
538
593
 
539
- p Kind::Maybe[object].try(:upcase) # nil
594
+ # --
540
595
 
541
- p Kind::Maybe[object].try { |value| value.upcase } # nil
542
- ```
596
+ Add.call(1) # #<Kind::Maybe::None:0x0000... @value=nil>
597
+ Add.call({}) # #<Kind::Maybe::None:0x0000... @value=nil>
598
+ Add.call(a: 1) # #<Kind::Maybe::None:0x0000... @value=nil>
599
+ Add.call(b: 2) # #<Kind::Maybe::None:0x0000... @value=nil>
543
600
 
544
- [⬆️ Back to Top](#table-of-contents-)
601
+ Add.call(a:1, b: 2) # #<Kind::Maybe::Some:0x0000... @value=3>
602
+
603
+ # --
604
+
605
+ Kind::Maybe[a: 1, b: 2].then(&Add).value_or(0) # 3
606
+
607
+ Kind::Maybe[1].then(&Add).value_or(0) # 0
608
+ Kind::Maybe['2'].then(&Add).value_or(0) # 0
609
+ Kind::Maybe[nil].then(&Add).value_or(0) # 0
610
+ ```
545
611
 
546
612
  ### Kind.of.Maybe()
547
613
 
@@ -598,6 +664,26 @@ result2 =
598
664
  puts result2 # 35
599
665
  ```
600
666
 
667
+ #### Replacing blocks by lambdas
668
+
669
+ ```ruby
670
+ Add = -> params do
671
+ a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
672
+
673
+ a + b if Kind.of.Numeric.instance?(a, b)
674
+ end
675
+
676
+ # --
677
+
678
+ Kind::Optional[a: 1, b: 2].then(&Add).value_or(0) # 3
679
+
680
+ # --
681
+
682
+ Kind::Optional[1].then(&Add).value_or(0) # 0
683
+ Kind::Optional['2'].then(&Add).value_or(0) # 0
684
+ Kind::Optional[nil].then(&Add).value_or(0) # 0
685
+ ```
686
+
601
687
  **Note:** The `Kind.of.Optional` is available to check if some value is a `Kind::Optional`.
602
688
 
603
689
  [⬆️ Back to Top](#table-of-contents-)
@@ -709,6 +795,44 @@ end
709
795
 
710
796
  [⬆️ Back to Top](#table-of-contents-)
711
797
 
798
+ ### Kind::Maybe#try
799
+
800
+ 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.
801
+
802
+ ```ruby
803
+ object = 'foo'
804
+
805
+ p Kind::Maybe[object].try(:upcase) # "FOO"
806
+
807
+ p Kind::Maybe[{}].try(:fetch, :number, 0) # 0
808
+
809
+ p Kind::Maybe[{number: 1}].try(:fetch, :number) # 1
810
+
811
+ p Kind::Maybe[object].try { |value| value.upcase } # "FOO"
812
+
813
+ #############
814
+ # Nil value #
815
+ #############
816
+
817
+ object = nil
818
+
819
+ p Kind::Maybe[object].try(:upcase) # nil
820
+
821
+ p Kind::Maybe[object].try { |value| value.upcase } # nil
822
+
823
+ #########################
824
+ # Kind::Undefined value #
825
+ #########################
826
+
827
+ object = Kind::Undefined
828
+
829
+ p Kind::Maybe[object].try(:upcase) # nil
830
+
831
+ p Kind::Maybe[object].try { |value| value.upcase } # nil
832
+ ```
833
+
834
+ [⬆️ Back to Top](#table-of-contents-)
835
+
712
836
  ## Kind::Validator (ActiveModel::Validations)
713
837
 
714
838
  This module enables the capability to validate types via [`ActiveModel::Validations >= 3.2, < 6.1.0`](https://api.rubyonrails.org/classes/ActiveModel/Validations.html). e.g
@@ -839,7 +963,6 @@ Kind::Validator.default_strategy = :instance_of
839
963
  ```
840
964
 
841
965
  And these are the available options to define the default strategy:
842
- - `is_a`
843
966
  - `kind_of` *(default)*
844
967
  - `instance_of`
845
968
 
data/lib/kind.rb CHANGED
@@ -29,6 +29,12 @@ module Kind
29
29
 
30
30
  private_constant :MODULE_OR_CLASS
31
31
 
32
+ private_class_method def self.__checkers__
33
+ @__checkers__ ||= {}
34
+ end
35
+
36
+ __checkers__
37
+
32
38
  def self.of(kind = Undefined, object = Undefined)
33
39
  return Of if kind == Undefined && object == Undefined
34
40
 
@@ -45,8 +51,8 @@ module Kind
45
51
  end
46
52
  end
47
53
 
48
- private_class_method def self.__checkers__
49
- @__checkers__ ||= {}
54
+ def self.of?(kind, *args)
55
+ Kind.of(kind).instance?(*args)
50
56
  end
51
57
 
52
58
  # --------------------- #
@@ -90,6 +96,10 @@ module Kind
90
96
  def self.__is_instance__(value); class?(value); end
91
97
  end)
92
98
 
99
+ def self.Class?(*args)
100
+ Kind::Of::Class.instance?(*args)
101
+ end
102
+
93
103
  # -- Module
94
104
 
95
105
  def self.Module(object = Undefined)
@@ -136,6 +146,10 @@ module Kind
136
146
  def self.__is_instance__(value); class?(value); end
137
147
  end)
138
148
 
149
+ def self.Module?(*args)
150
+ Kind::Of::Module.instance?(*args)
151
+ end
152
+
139
153
  # -- Boolean
140
154
 
141
155
  def self.Boolean(object = Undefined, options = Empty::HASH)
@@ -187,6 +201,10 @@ module Kind
187
201
  end
188
202
  end)
189
203
 
204
+ def self.Boolean?(*args)
205
+ Kind::Of::Boolean.instance?(*args)
206
+ end
207
+
190
208
  # -- Lambda
191
209
 
192
210
  def self.Lambda(object = Undefined, options = Empty::HASH)
@@ -231,6 +249,10 @@ module Kind
231
249
  end
232
250
  end)
233
251
 
252
+ def self.Lambda?(*args)
253
+ Kind::Of::Lambda.instance?(*args)
254
+ end
255
+
234
256
  # -- Callable
235
257
 
236
258
  def self.Callable(object = Undefined, options = Empty::HASH)
@@ -279,6 +301,10 @@ module Kind
279
301
  end
280
302
  end)
281
303
 
304
+ def self.Callable?(*args)
305
+ Kind::Of::Callable.instance?(*args)
306
+ end
307
+
282
308
  # ---------------------- #
283
309
  # Built-in type checkers #
284
310
  # ---------------------- #
data/lib/kind/checker.rb CHANGED
@@ -18,21 +18,29 @@ module Kind
18
18
  instance(value, options)
19
19
  end
20
20
 
21
- def instance?(value = Kind::Undefined)
22
- return __is_instance__(value) if value != Kind::Undefined
23
-
24
- to_proc
21
+ def to_proc
22
+ @to_proc ||=
23
+ -> checker { -> value { checker.instance(value) } }.call(self)
25
24
  end
26
25
 
27
26
  def __is_instance__(value)
28
- value.is_a?(__kind)
27
+ value.kind_of?(__kind)
29
28
  end
30
29
 
31
- def to_proc
32
- @to_proc ||=
30
+ def is_instance_to_proc
31
+ @is_instance_to_proc ||=
33
32
  -> checker { -> value { checker.__is_instance__(value) } }.call(self)
34
33
  end
35
34
 
35
+ def instance?(*args)
36
+ return is_instance_to_proc if args.empty?
37
+
38
+ return args.all? { |object| __is_instance__(object) } if args.size > 1
39
+
40
+ arg = args[0]
41
+ arg == Kind::Undefined ? is_instance_to_proc : __is_instance__(arg)
42
+ end
43
+
36
44
  def or_nil(value)
37
45
  return value if instance?(value)
38
46
  end
@@ -41,6 +49,15 @@ module Kind
41
49
  or_nil(value) || Kind::Undefined
42
50
  end
43
51
 
52
+ def __as_maybe__(value)
53
+ Kind::Maybe.new(or_nil(value))
54
+ end
55
+
56
+ def as_maybe_to_proc
57
+ @as_maybe_to_proc ||=
58
+ -> checker { -> value { checker.__as_maybe__(value) } }.call(self)
59
+ end
60
+
44
61
  def as_maybe(value = Kind::Undefined)
45
62
  return __as_maybe__(value) if value != Kind::Undefined
46
63
 
@@ -50,15 +67,6 @@ module Kind
50
67
  def as_optional(value = Kind::Undefined)
51
68
  as_maybe(value)
52
69
  end
53
-
54
- def __as_maybe__(value)
55
- Kind::Maybe.new(or_nil(value))
56
- end
57
-
58
- def as_maybe_to_proc
59
- @as_maybe_to_proc ||=
60
- -> checker { -> value { checker.__as_maybe__(value) } }.call(self)
61
- end
62
70
  end
63
71
 
64
72
  private_constant :Checkable
data/lib/kind/maybe.rb CHANGED
@@ -16,7 +16,7 @@ module Kind
16
16
  attr_reader :value
17
17
 
18
18
  def initialize(value)
19
- @value = value
19
+ @value = value.kind_of?(Result) ? value.value : value
20
20
  end
21
21
 
22
22
  def value_or(method_name = Undefined, &block)
@@ -44,7 +44,7 @@ module Kind
44
44
  def value_or(default = Undefined, &block)
45
45
  raise ArgumentError, INVALID_DEFAULT_ARG if default == Undefined && !block
46
46
 
47
- Maybe::Value.some?(default) ? default : block.call
47
+ default != Undefined ? default : block.call
48
48
  end
49
49
 
50
50
  def none?; true; end
@@ -79,6 +79,7 @@ module Kind
79
79
  def map(&fn)
80
80
  result = fn.call(@value)
81
81
 
82
+ return result if Maybe::None === result
82
83
  return NONE_WITH_NIL_VALUE if result == nil
83
84
  return NONE_WITH_UNDEFINED_VALUE if result == Undefined
84
85
 
@@ -98,13 +99,37 @@ module Kind
98
99
 
99
100
  def self.new(value)
100
101
  result_type = Maybe::Value.none?(value) ? None : Some
101
- result_type.new(value.is_a?(Result) ? value.value : value)
102
+ result_type.new(value)
102
103
  end
103
104
 
104
105
  def self.[](value);
105
106
  new(value)
106
107
  end
108
+
109
+ def self.none
110
+ NONE_WITH_NIL_VALUE
111
+ end
112
+
113
+ VALUE_CANT_BE_NONE = "value can't be nil or Kind::Undefined".freeze
114
+
115
+ private_constant :VALUE_CANT_BE_NONE
116
+
117
+ def self.some(value)
118
+ return Maybe::Some.new(value) if Value.some?(value)
119
+
120
+ raise ArgumentError, VALUE_CANT_BE_NONE
121
+ end
107
122
  end
108
123
 
109
124
  Optional = Maybe
125
+
126
+ None = Maybe.none
127
+
128
+ def self.None
129
+ Kind::None
130
+ end
131
+
132
+ def self.Some(value)
133
+ Maybe.some(value)
134
+ end
110
135
  end
data/lib/kind/types.rb CHANGED
@@ -12,7 +12,17 @@ module Kind
12
12
 
13
13
  return Kind::Of::%{kind_name} if object == Undefined && default.nil?
14
14
 
15
- Kind::Of.(::%{kind_name_to_check}, (object || default))
15
+ is_instance = Kind::Of::%{kind_name}.__is_instance__(object)
16
+
17
+ return object if is_instance
18
+
19
+ Kind::Of.(::%{kind_name_to_check}, object && default ? default : object || default)
20
+ end
21
+ RUBY
22
+
23
+ KIND_OF_IS = <<-RUBY
24
+ def self.%{method_name}?(*args)
25
+ Kind::Of::%{kind_name}.instance?(*args)
16
26
  end
17
27
  RUBY
18
28
 
@@ -93,6 +103,7 @@ module Kind
93
103
 
94
104
  kind_of_mod.instance_eval(KIND_OF % params)
95
105
  kind_of_mod.const_set(method_name, kind_checker)
106
+ kind_of_mod.instance_eval(KIND_OF_IS % params)
96
107
  end
97
108
 
98
109
  unless kind_is_mod.respond_to?(method_name)
data/lib/kind/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kind
4
- VERSION = '2.0.0'
4
+ VERSION = '2.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kind
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-07 00:00:00.000000000 Z
11
+ date: 2020-05-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple type system (at runtime) for Ruby - free of dependencies.
14
14
  email: