Class: MonadOxide::Option

Inherits:
Object
  • Object
show all
Defined in:
lib/option.rb

Overview

An Option is a chainable series of sequential transformations. The Option structure contains a ‘Some<A> | None`. This is the central location for documentation between both `Some’ and ‘None’. It is best to think of any given ‘Some’ or ‘None’ as an ‘Option’ instead. All methods on ‘Some’ are present on ‘None’ and vice versa. This way we can interchange one for the other during virtually any call.

This is a base-class only, and you should never see instances of these in the wild.

Direct Known Subclasses

None, Some

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Option

Returns a new instance of Option.

Raises:

  • (NoMethodError)


48
49
50
# File 'lib/option.rb', line 48

def initialize(data)
  raise NoMethodError.new('Do not use Option directly. See Some and None.')
end

Instance Method Details

#and_then(f = nil) { ... } ⇒ Some<B> | None

For ‘Some’, invokes ‘f’ or the block with the data and returns the Option returned from that.

For ‘None’, returns itself and the function/block are ignored.

This method is used for control flow based on ‘Option’ values.

‘and_then’ is desirable for chaining together other Option based operations, or doing transformations where flipping from a ‘Some’ to a ‘None’ is desired. In cases where there is little/no risk of a ‘None’ state, @see Option#map.

The ‘None’ equivalent operation is @see Option#or_else.

The return type is enforced.

Parameters:

  • f (Proc<A, Option<B>>) (defaults to: nil)

    The function to call. Could be a block instead. Takes an [A=Object] and must return a [Option<B>].

Yields:

  • Will yield a block that takes an A and returns a Option<B>. Same as ‘f’ parameter.

Returns:

  • (Some<B> | None)

    A new Option from ‘f’ or the block. If ‘f’ returns a non-Option, this will raise ‘OptionReturnExpectedError’.

Raises:



145
146
147
# File 'lib/option.rb', line 145

def and_then(f=nil, &block)
  raise OptionMethodNotImplementedError.new()
end

#inspect_none(f = nil) { ... } ⇒ Option

In the case of ‘None’, applies ‘f’ or the block and returns the same ‘None’. No changes are applied. This is ideal for logging. For ‘Some’, this method falls through.

Parameters:

  • f (Proc<B>) (defaults to: nil)

    The function to call. Could be a block instead. Takes nothing, the return is ignored.

Yields:

  • Will yield a block that takes nothing, the return is ignored. Same as ‘f’ parameter.

Returns:

Raises:



117
118
119
# File 'lib/option.rb', line 117

def inspect_none(f=nil, &block)
  raise OptionMethodNotImplementedError.new()
end

#inspect_some(f = nil) { ... } ⇒ Option<A>

In the case of ‘Some’, applies ‘f’ or the block over the data and returns the same ‘Some’. No changes are applied. This is ideal for logging. For ‘None’, this method falls through.

Parameters:

  • f (Proc<A, B>) (defaults to: nil)

    The function to call. Could be a block instead. Takes an [A] the return is ignored.

Yields:

  • Will yield a block that takes an A the return is ignored. Same as ‘f’ parameter.

Returns:

  • (Option<A>)

    returns self.

Raises:



104
105
106
# File 'lib/option.rb', line 104

def inspect_some(f=nil, &block)
  raise OptionMethodNotImplementedError.new()
end

#map(f = nil) { ... } ⇒ Option<B>

In the case of ‘Some’, applies ‘f’ or the block over the data and returns a new ‘Some’ with the returned value. For ‘None’, this method falls through.

Parameters:

  • f (Proc<A, B>) (defaults to: nil)

    The function to call. Could be a block instead. Takes an [A=Object] and returns a B.

Yields:

  • Will yield a block that takes an A and returns a B. Same as ‘f’ parameter.

Returns:

  • (Option<B>)

    A new ‘Option<B>’ whose ‘B’ is the return of ‘f’ or the block for ‘Some’. For ‘None’, returns self.

Raises:



78
79
80
# File 'lib/option.rb', line 78

def map(f=nil, &block)
  raise OptionMethodNotImplementedError.new()
end

#map_none(f = nil) { ... } ⇒ Option<B>

In the case of ‘None’, applies ‘f’ or the block and returns a new ‘Option’ with the returned value. For ‘Some’, this method falls through.

Parameters:

  • f (Proc<B>) (defaults to: nil)

    The function to call. Could be a block instead. Takes nothing and returns a B.

Yields:

  • Will yield a block that takes nothing and returns a B. Same as ‘f’ parameter.

Returns:

  • (Option<B>)

    A new ‘Option<B>’ whose ‘B’ is the return of ‘f’ or the block for ‘None’. For ‘Some’, returns self.

Raises:



91
92
93
# File 'lib/option.rb', line 91

def map_none(f=nil, &block)
  raise OptionMethodNotImplementedError.new()
end

#match(matcher) ⇒ R

Use pattern matching to work with both Some and None variants. This is useful when it is desirable to have both variants handled in the same location. It can also be useful when either variant can coerced into a non-Option type.

Ruby has no built-in pattern matching, but the next best thing is a Hash using the Option classes themselves as the keys.

Tests for this are found in Some and None’s tests.

upon.

Parameters:

  • matcher (Hash<Class, Proc<T, R>] matcher The matcher to match)

    atcher [Hash<Class, Proc<T, R>] matcher The matcher to match

Options Hash (matcher):

  • MonadOxide::Some (Proc)

    The branch to execute for Some.

  • MonadOxide::None (Proc)

    The branch to execute for None.

Returns:

  • (R)

    The return value of the executed Proc.



210
211
212
213
214
215
216
# File 'lib/option.rb', line 210

def match(matcher)
  if self.kind_of?(None)
    matcher[self.class].call()
  else
    matcher[self.class].call(@data)
  end
end

#none?Boolean

Determine if this is a MonadOxide::None. otherwise.

Returns:

  • (Boolean)

    ‘true` if this is a MonadOxide::None, `false`



64
65
66
# File 'lib/option.rb', line 64

def none?()
  false
end

#or_else(f = nil) { ... } ⇒ Some<B> | None

For ‘None’, invokes ‘f’ or the block and returns the Option returned from that.

For ‘Some’, returns itself and the function/block are ignored.

This method is used for control flow based on ‘Option’ values.

‘or_else’ is desirable for chaining together other Option based operations, or doing transformations where flipping from a ‘None’ to a ‘Some’ is desired.

The ‘Some’ equivalent operation is @see Option#and_then.

The return type is enforced.

Parameters:

  • f (Proc<Option<B>>) (defaults to: nil)

    The function to call. Could be a block instead. Takes nothing and must return a [Option<B>].

Yields:

  • Will yield a block that takes nothing and returns a Option<B>. Same as ‘f’ parameter.

Returns:

  • (Some<B> | None)

    A new Option from ‘f’ or the block. If ‘f’ returns a non-Option, this will raise ‘OptionReturnExpectedError’.

Raises:



172
173
174
# File 'lib/option.rb', line 172

def or_else(f=nil, &block)
  raise OptionMethodNotImplementedError.new()
end

#some?Boolean

Determine if this is a MonadOxide::Some. otherwise.

Returns:

  • (Boolean)

    ‘true` if this is a MonadOxide::Some, `false`



56
57
58
# File 'lib/option.rb', line 56

def some?()
  false
end

#unwrapA

Dangerously access the ‘Option’ data. If this is a ‘None’, an exception will be raised. It is recommended to use this for tests only.

Returns:

  • (A)
    • The inner data of this ‘Some’.

Raises:



181
182
183
# File 'lib/option.rb', line 181

def unwrap()
  raise OptionMethodNotImplementedError.new()
end

#unwrap_nonenil

Dangerously access the ‘Option’ data. If this is a ‘Some’, an exception will be raised. It is recommended to use this for tests only.

Returns:

  • (nil)
    • Returns nil for ‘None’.

Raises:



190
191
192
# File 'lib/option.rb', line 190

def unwrap_none()
  raise OptionMethodNotImplementedError.new()
end