fear 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/fear/option.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  module Fear
2
- # Represents optional values. Instances of `Option`
3
- # are either an instance of `Some` or the object `None`.
2
+ # Represents optional values. Instances of +Option+
3
+ # are either an instance of +Some+ or the object +None+.
4
4
  #
5
- # @example The most idiomatic way to use an `Option` instance is to treat it as a collection
5
+ # @example The most idiomatic way to use an +Option+ instance is to treat it as a collection
6
6
  # name = Option(params[:name])
7
7
  # upper = name.map(&:strip).select { |n| n.length != 0 }.map(&:upcase)
8
8
  # puts upper.get_or_else('')
9
9
  #
10
- # This allows for sophisticated chaining of `Option` values without
10
+ # This allows for sophisticated chaining of +Option+ values without
11
11
  # having to check for the existence of a value.
12
12
  #
13
- # @example A less-idiomatic way to use `Option` values is via pattern matching
13
+ # @example A less-idiomatic way to use +Option+ values is via pattern matching
14
14
  # name = Option(params[:name])
15
15
  # case name
16
16
  # when Some
@@ -27,61 +27,144 @@ module Fear
27
27
  # puts name.strip.upcase
28
28
  # end
29
29
  #
30
- # @example #select
31
- # User.find(params[:id]).select do |user|
32
- # user.posts.count > 0
33
- # end #=> Some(User)
30
+ # @!method get_or_else(*args)
31
+ # Returns the value from this +Some+ or evaluates the given
32
+ # default argument if this is a +None+.
33
+ # @overload get_or_else(&default)
34
+ # @yieldreturn [any]
35
+ # @return [any]
36
+ # @example
37
+ # Some(42).get_or_else { 24/2 } #=> 42
38
+ # None().get_or_else { 24/2 } #=> 12
39
+ # @overload get_or_else(default)
40
+ # @return [any]
41
+ # @example
42
+ # Some(42).get_or_else(12) #=> 42
43
+ # None().get_or_else(12) #=> 12
34
44
  #
35
- # User.find(params[:id]).select do |user|
36
- # user.posts.count > 0
37
- # end #=> None
45
+ # @!method include?(other_value)
46
+ # Returns +true+ if it has an element that is equal
47
+ # (as determined by +==+) to +other_value+, +false+ otherwise.
48
+ # @param [any]
49
+ # @return [Boolean]
50
+ # @example
51
+ # Some(17).include?(17) #=> true
52
+ # Some(17).include?(7) #=> false
53
+ # None().include?(17) #=> false
38
54
  #
39
- # User.find(params[:id])
40
- # .select(&:confirmed?)
41
- # .map(&:posts)
42
- # .inject(0, &:count)
55
+ # @!method each(&block)
56
+ # Performs the given block if this is a +Some+.
57
+ # @yieldparam [any] value
58
+ # @yieldreturn [void]
59
+ # @return [Option] itself
60
+ # @example
61
+ # Some(17).each do |value|
62
+ # puts value
63
+ # end #=> prints 17
43
64
  #
44
- # @example #reject
45
- # Some(42).reject { |v| v > 0 } #=> None
46
- # Some(42).reject { |v| v < 0 } #=> Some(42)
47
- # None().reject { |v| v > 0 } #=> None
65
+ # None().each do |value|
66
+ # puts value
67
+ # end #=> does nothing
68
+ #
69
+ # @!method map(&block)
70
+ # Maps the given block to the value from this +Some+ or
71
+ # returns this if this is a +None+
72
+ # @yieldparam [any] value
73
+ # @yieldreturn [any]
74
+ # @example
75
+ # Some(42).map { |v| v/2 } #=> Some(21)
76
+ # None().map { |v| v/2 } #=> None()
77
+ #
78
+ # @!method flat_map(&block)
79
+ # Returns the given block applied to the value from this +Some+
80
+ # or returns this if this is a +None+
81
+ # @yieldparam [any] value
82
+ # @yieldreturn [Option]
83
+ # @return [Option]
84
+ # @example
85
+ # Some(42).flat_map { |v| Some(v/2) } #=> Some(21)
86
+ # None().flat_map { |v| Some(v/2) } #=> None()
87
+ #
88
+ # @!method to_a
89
+ # Returns an +Array+ containing the +Some+ value or an
90
+ # empty +Array+ if this is a +None+
91
+ # @return [Array]
92
+ # @example
93
+ # Some(42).to_a #=> [21]
94
+ # None().to_a #=> []
95
+ #
96
+ # @!method any?(&predicate)
97
+ # Returns +false+ if +None+ or returns the result of the
98
+ # application of the given predicate to the +Some+ value.
99
+ # @yieldparam [any] value
100
+ # @yieldreturn [Boolean]
101
+ # @return [Boolean]
102
+ # @example
103
+ # Some(12).any?( |v| v > 10) #=> true
104
+ # Some(7).any?( |v| v > 10) #=> false
105
+ # None().any?( |v| v > 10) #=> false
106
+ #
107
+ # @!method select(&predicate)
108
+ # Returns self if it is nonempty and applying the predicate to this
109
+ # +Option+'s value returns +true+. Otherwise, return +None+.
110
+ # @yieldparam [any] value
111
+ # @yieldreturn [Boolean]
112
+ # @return [Option]
113
+ # @example
114
+ # Some(42).select { |v| v > 40 } #=> Success(21)
115
+ # Some(42).select { |v| v < 40 } #=> None()
116
+ # None().select { |v| v < 40 } #=> None()
117
+ #
118
+ # @!method reject(&predicate)
119
+ # Returns +Some+ if applying the predicate to this
120
+ # +Option+'s value returns +false+. Otherwise, return +None+.
121
+ # @yieldparam [any] value
122
+ # @yieldreturn [Boolean]
123
+ # @return [Option]
124
+ # @example
125
+ # Some(42).reject { |v| v > 40 } #=> None
126
+ # Some(42).reject { |v| v < 40 } #=> Some(42)
127
+ # None().reject { |v| v < 40 } #=> None
128
+ #
129
+ # @!method get
130
+ # @return [any] the +Option+'s value.
131
+ # @raise [NoSuchElementError] if the option is empty.
132
+ #
133
+ # @!method empty?
134
+ # Returns +true+ if the +Option+ is +None+, +false+ otherwise.
135
+ # @return [Boolean]
136
+ # @example
137
+ # Some(42).empty? #=> false
138
+ # None().empty? #=> true
48
139
  #
49
140
  # @see https://github.com/scala/scala/blob/2.11.x/src/library/scala/Option.scala
50
141
  #
51
142
  module Option
143
+ # @private
52
144
  def left_class
53
145
  None
54
146
  end
55
147
 
148
+ # @private
56
149
  def right_class
57
150
  Some
58
151
  end
59
152
 
60
- # @return [true, false] true if the option is `None`,
61
- # false otherwise.
62
- #
63
- def empty?
64
- is_a?(None)
65
- end
66
-
67
- # Returns the option's value if it is nonempty,
68
- # or `nil` if it is empty. Useful for unwrapping
69
- # option's value.
70
- #
71
- # @return [Object, nil] the option's value if it is
72
- # nonempty or `nil` if it is empty
73
- #
153
+ # Include this mixin to access convenient factory methods.
74
154
  # @example
75
- # Option(24).or_nil #=> 24
76
- # Option(nil).or_nil #=> nil
155
+ # include Fear::Option::Mixin
156
+ #
157
+ # Option(17) #=> #<Fear::Some value=17>
158
+ # Option(nil) #=> #<Fear::None>
159
+ # Some(17) #=> #<Fear::Some value=17>
160
+ # None() #=> #<Fear::None>
77
161
  #
78
- def or_nil
79
- get_or_else { nil }
80
- end
81
-
82
162
  module Mixin
163
+ # An +Option+ factory which creates +Some+ if the argument is
164
+ # not +nil+, and +None+ if it is +nil+.
83
165
  # @param value [any]
84
166
  # @return [Some, None]
167
+ #
85
168
  def Option(value)
86
169
  if value.nil?
87
170
  None()
data/lib/fear/right.rb CHANGED
@@ -3,13 +3,21 @@ module Fear
3
3
  include Either
4
4
  include RightBiased::Right
5
5
 
6
- # Returns `Left(default)` if the given predicate
7
- # does not hold for the right value, otherwise, returns `Right`.
8
- #
6
+ # @return [true]
7
+ def right?
8
+ true
9
+ end
10
+ alias success? right?
11
+
12
+ # @return [false]
13
+ def left?
14
+ false
15
+ end
16
+ alias failure? left?
17
+
9
18
  # @param default [Proc, any]
10
19
  # @return [Either]
11
- #
12
- def select(default)
20
+ def select_or_else(default)
13
21
  if yield(value)
14
22
  self
15
23
  else
@@ -17,38 +25,35 @@ module Fear
17
25
  end
18
26
  end
19
27
 
28
+ # @return [Either]
29
+ def select
30
+ if yield(value)
31
+ self
32
+ else
33
+ Left.new(value)
34
+ end
35
+ end
36
+
20
37
  # @return [Left] value in `Left`
21
38
  def swap
22
39
  Left.new(value)
23
40
  end
24
41
 
25
- # @param reduce_right [Proc] the function to apply if this is a `Right`
26
- # @return [any] Applies `reduce_right` to the value.
27
- #
42
+ # @param reduce_right [Proc]
43
+ # @return [any]
28
44
  def reduce(_, reduce_right)
29
45
  reduce_right.call(value)
30
46
  end
31
47
 
32
- # Joins an `Either` through `Right`.
33
- #
34
- # This method requires that the right side of this `Either` is itself an
35
- # Either type.
36
- #
37
- # This method, and `join_left`, are analogous to `Option#flatten`
38
- #
39
48
  # @return [Either]
40
- # @raise [TypeError] if it does not contain `Either`.
41
- #
49
+ # @raise [TypeError]
42
50
  def join_right
43
51
  value.tap do |v|
44
52
  Utils.assert_type!(v, Either)
45
53
  end
46
54
  end
47
55
 
48
- # Joins an `Either` through `Left`.
49
- #
50
56
  # @return [self]
51
- #
52
57
  def join_left
53
58
  self
54
59
  end
@@ -1,4 +1,5 @@
1
1
  module Fear
2
+ # @private
2
3
  module RightBiased
3
4
  # Performs necessary interface and type checks.
4
5
  #
@@ -31,11 +32,11 @@ module Fear
31
32
  end
32
33
  end
33
34
 
34
- # @!method get_or_else(default)
35
+ # @overload get_or_else(default)
35
36
  # @param default [any]
36
37
  # @return [any] the `#value`.
37
38
  #
38
- # @!method get_or_else
39
+ # @overload get_or_else(&default)
39
40
  # @return [any] the `#value`.
40
41
  #
41
42
  def get_or_else(*_args)
@@ -43,17 +44,12 @@ module Fear
43
44
  end
44
45
 
45
46
  # @param [any]
46
- # @return [Boolean] `true` if it has an element that is equal
47
- # (as determined by `==`) to `other_value`, `false` otherwise.
48
- #
47
+ # @return [Boolean]
49
48
  def include?(other_value)
50
49
  value == other_value
51
50
  end
52
51
 
53
- # Executes the given side-effecting block.
54
- #
55
52
  # @return [self]
56
- #
57
53
  def each
58
54
  yield(value)
59
55
  self
@@ -98,7 +94,7 @@ module Fear
98
94
  # @param default [any]
99
95
  # @return [any] default value
100
96
  #
101
- # @!method get_or_else
97
+ # @!method get_or_else(&default)
102
98
  # @return [any] result of evaluating a block.
103
99
  #
104
100
  def get_or_else(*args)
data/lib/fear/some.rb CHANGED
@@ -11,15 +11,22 @@ module Fear
11
11
  @value = value
12
12
  end
13
13
 
14
- # @return option's value
14
+ # @return [any]
15
15
  def get
16
16
  @value
17
17
  end
18
18
 
19
- # @return [Option] self if this `Option` is nonempty and
20
- # applying the `predicate` to this option's value
21
- # returns true. Otherwise, return `None`.
22
- #
19
+ # @return [any]
20
+ def or_nil
21
+ @value
22
+ end
23
+
24
+ # @return [false]
25
+ def empty?
26
+ false
27
+ end
28
+
29
+ # @return [Option]
23
30
  def select
24
31
  if yield(value)
25
32
  self
@@ -28,9 +35,7 @@ module Fear
28
35
  end
29
36
  end
30
37
 
31
- # @return [Option] if applying the `predicate` to this
32
- # option's value returns false. Otherwise, return `None`.
33
- #
38
+ # @return [Option]
34
39
  def reject
35
40
  if yield(value)
36
41
  None.new
data/lib/fear/success.rb CHANGED
@@ -7,27 +7,32 @@ module Fear
7
7
  attr_reader :value
8
8
  protected :value
9
9
 
10
+ # @param [any]
10
11
  def initialize(value)
11
12
  @value = value
12
13
  end
13
14
 
15
+ # @return [any]
14
16
  def get
15
17
  @value
16
18
  end
17
19
 
20
+ # @return [Boolean]
18
21
  def success?
19
22
  true
20
23
  end
21
24
 
22
- # @return [Success] self
25
+ # @return [false]
26
+ def failure?
27
+ false
28
+ end
29
+
30
+ # @return [Success]
23
31
  def or_else
24
32
  self
25
33
  end
26
34
 
27
- # Transforms a nested `Try`, ie, a `Success` of `Success``,
28
- # into an un-nested `Try`, ie, a `Success`.
29
35
  # @return [Try]
30
- #
31
36
  def flatten
32
37
  if value.is_a?(Try)
33
38
  value.flatten
@@ -36,12 +41,9 @@ module Fear
36
41
  end
37
42
  end
38
43
 
39
- # Converts this to a `Failure` if the predicate
40
- # is not satisfied.
41
44
  # @yieldparam [any] value
42
45
  # @yieldreturn [Boolean]
43
46
  # @return [Try]
44
- #
45
47
  def select
46
48
  if yield(value)
47
49
  self
@@ -52,14 +54,12 @@ module Fear
52
54
  Failure.new(error)
53
55
  end
54
56
 
55
- # @return [Success] self
56
- #
57
+ # @return [Success]
57
58
  def recover_with
58
59
  self
59
60
  end
60
61
 
61
- # @return [Success] self
62
- #
62
+ # @return [Success]
63
63
  def recover
64
64
  self
65
65
  end
@@ -77,5 +77,10 @@ module Fear
77
77
  rescue => error
78
78
  Failure.new(error)
79
79
  end
80
+
81
+ # @return [Right]
82
+ def to_either
83
+ Right.new(value)
84
+ end
80
85
  end
81
86
  end