Class: Divergent::Maybe

Inherits:
Object
  • Object
show all
Includes:
Monad
Defined in:
lib/divergent/maybe.rb

Overview

Optional values.

An instance of Some or the object None.

The most idiomatic way to use an Maybe instance is to treat it as a collection or monad and use ‘map`, `fmap`, `filter`, or `each`.

Direct Known Subclasses

Some

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Monad

included

Class Method Details

.emptyObject

An Maybe factory which return None.

This always return the same None object.

Example:

Maybe.empty == Maybe.empty


43
44
45
# File 'lib/divergent/maybe.rb', line 43

def self.empty
  None
end

.unit(v) ⇒ Object

An factory which creates Some(v) if the argument is not nil, and None if it is nil.

Examples:

Maybe.unit(1)   # => Some(1)
Maybe.unit(nil) # => None


25
26
27
28
29
30
31
# File 'lib/divergent/maybe.rb', line 25

def self.unit(v)
  if v.nil?
    None
  else
    Some.new(v)
  end
end

Instance Method Details

#all?Boolean

Return true if it is empty or the predicate block evals to true when applying to the maybe’s value.

Examples:

Maybe.unit(1).all?{ |v| v == 1} #=> true
Maybe.unit(1).all?{ |v| v == 2} #=> false
Maybe.empty.all?{ |v| v == 1} #=> true

Returns:

  • (Boolean)


173
174
175
# File 'lib/divergent/maybe.rb', line 173

def all?() # :yields: v
  empty? || yield(get)
end

#any?Boolean

Return true if it is not empty and the predicate block evals to true.

Examples:

Maybe.unit(1).any?{ |v| v == 1} #=> true
Maybe.unit(1).any?{ |v| v == 2} #=> false
Maybe.empty.any?{ |v| v == 1} #=> false

Returns:

  • (Boolean)


158
159
160
# File 'lib/divergent/maybe.rb', line 158

def any?() # :yields: v
  !empty? && yield(get)
end

#each {|get| ... } ⇒ Object

Apply the given block to the maybe’s value if not empty. Otherwise, do nothing.

Yields:



179
180
181
# File 'lib/divergent/maybe.rb', line 179

def each() # :yields: v
  yield(get) unless empty?
end

#empty?Boolean

Return true if the maybe is None, false otherwise.

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


71
72
73
# File 'lib/divergent/maybe.rb', line 71

def empty?
  raise NotImplementedError
end

#filterObject

Return this maybe if it is not empty and the predicate block evals to true. Otherwise, return None.



128
129
130
131
132
# File 'lib/divergent/maybe.rb', line 128

def filter() # :yields: v
  fmap do |v|
    yield(v) ? Maybe.unit(v) : None
  end
end

#fmapObject

Returns the result of applying block to this Maybe value, if this value is not empty. Return ‘None` if this value is empty.

Slightly different from ‘map` in that block is expected to return an instance of `Maybe`.

Examples

Maybe.unit(1).fmap { |v| Maybe.unit(v + 1) } # => Some(2)
some_hash = {}
Maybe.unit(:a).fmap { |v| Maybe.unit(some_hash[v]) } # => None


61
62
63
64
65
66
67
# File 'lib/divergent/maybe.rb', line 61

def fmap() # :yields: v
  if empty?
    None
  else
    yield(get)
  end
end

#getObject

Return the maybe’s value.

Notes: the maybe should not be empty.

otherwise, raise Standarderror.

Raises:

  • (NotImplementedError)


82
83
84
# File 'lib/divergent/maybe.rb', line 82

def get
  raise NotImplementedError
end

#get_or_else(v) ⇒ Object

Returns the maybe’s value if the maybe is nonempty, otherwise return the ‘v`.



89
90
91
92
93
94
95
# File 'lib/divergent/maybe.rb', line 89

def get_or_else(v)
  if empty?
    v
  else
    get
  end
end

#include?(elem) ⇒ Boolean

Test whether the maybe contains a given elem.

Examples:

Maybe.unit(1).include?(1) #=> true
Maybe.unit(1).include?(2) #=> false
Maybe.empty.include?(1) #=> false

Returns:

  • (Boolean)


144
145
146
# File 'lib/divergent/maybe.rb', line 144

def include?(elem)
  !empty? && get == elem
end

#mapObject

Notes: This is similar to flat_map except here, block does not need to wrap its result in a maybe.



120
121
122
# File 'lib/divergent/maybe.rb', line 120

def map() # :yields: v
  fmap { |v| Maybe.unit(yield v) }
end

#or_else(v) ⇒ Object

Return this maybe id it is not empty, else return the ‘v`.

Note: This is similar to Maybe#get_or_else, but the v should be an instance of Maybe.



104
105
106
107
108
109
110
# File 'lib/divergent/maybe.rb', line 104

def or_else(v)
  if empty?
    v
  else
    self
  end
end

#to_aObject

Returns a singleton list containing the maybe’s value

if it is nonempty, or the empty list if empty.


185
186
187
188
189
190
191
# File 'lib/divergent/maybe.rb', line 185

def to_a
  if empty?
    []
  else
    [get]
  end
end