Module: Maybe

Includes:
Contracts::Core
Included in:
Just, Nothing
Defined in:
lib/maybe.rb

Overview

Maybe is a union type that is expressed in terms of Nothing and Just. It is useful for gracefully handling potentially null values:

Examples:

when value is non-null

User.create!(email: "[email protected]", name: "John Doe")

Maybe
  .from_nullable(User.find_by(email: "[email protected]"))
  .map {|user| user.name }
  .get_or_else { "NO NAME" }

#=> "John Doe"

when value is null

Maybe
  .from_nullable(User.find_by(email: "[email protected]"))
  .map {|user| user.name }
  .get_or_else { "NO NAME" }

#=> "NO NAME"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_nullable(value) ⇒ Object



101
102
103
# File 'lib/maybe.rb', line 101

def self.from_nullable(value)
  value.nil? ? Nothing.instance : Just.new(value)
end

.Just(value) ⇒ Object



66
67
68
# File 'lib/maybe.rb', line 66

def self.Just(value)
  Just.new(value)
end

.lift(f, fst, *rst) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/maybe.rb', line 170

def self.lift(f, fst, *rst)
  [fst, *rst]
    .reduce(Just([])) {|accum, maybe|
      accum.flat_map {|accum_|
        maybe.map {|maybe_| accum_ + [maybe_] }
      }
    }
    .ap( Just(->(args){ f.call(*args) }) )
end

.NothingObject



53
54
55
# File 'lib/maybe.rb', line 53

def self.Nothing
  Nothing.instance
end

.of(value) ⇒ Object



79
80
81
# File 'lib/maybe.rb', line 79

def self.of(value)
  Just.new(value)
end

.zip(fst, snd, *rest) ⇒ Object



131
132
133
134
135
136
137
# File 'lib/maybe.rb', line 131

def self.zip(fst, snd, *rest)
  [fst, snd, *rest].reduce(Just([])) do |accum, maybe|
    accum.flat_map do |accum_|
      maybe.map {|maybe_| accum_ + [maybe_] }
    end
  end
end

Instance Method Details

#ProcJust<Any>, Nothing

Takes a function and a set of Maybes, and attempts to apply the function and return the result wrapped in a Maybe.

Examples:

with a single instance of Just

Maybe.lift(->(n){ n ** 2 }, Maybe.Just(3))
#=> Just(9)

with a single instance of Nothing

Maybe.lift(->(n){ n ** 2 }, Maybe.Nothing)
#=> Nothing

with multiple instances of Just

Maybe.lift(->(x,y){ x + y }, Maybe.Just(1), Maybe.Just(2))
#=> Just(3)

with multiple instances of Nothing

Maybe.lift(->(x,y){ x + y }, Maybe.Nothing, Maybe.Nothing)
#=> Nothing

a mixture of Just and Nothing instances

Maybe.lift(->(x,y,z) { x + y + z }, Maybe.Just(1), Maybe.Nothing, Maybe.Just(2))
#=> Nothing

called with the wrong number of arguments

Maybe.lift(->(x,y) { x + y }, Maybe.Just(1))
#=> ArgumentError: wrong number of arguments (given 1, expected 2)

Parameters:

  • f (Proc)

    a function

  • m (Array<Just<Any>>, Array<Nothing>)

    a collection of Maybes

Returns:

  • (Just<Any>, Nothing)

    either the result wrapped in a Just, or Nothing



169
# File 'lib/maybe.rb', line 169

Contract Proc, C::Args[Maybe] => Maybe