class Concurrent::Maybe

@see github.com/purescript/purescript-maybe/blob/master/docs/Data.Maybe.md PureScript Data.Maybe
@see hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html Haskell Data.Maybe
render json: result.or(NullClient.new)
result = ClientService.new(10).find # returns a Maybe
# In a Rails controller…
@example Using Maybe with the Null Object Pattern
result.reason #=> ActiveRecord::RecordNotFound
result.just? #=> false
# – if the record was not found
result.value #=> #<Client id: 10, first_name: “Ryan”>
result.just? #=> true
# – if the record was found
end
Client.find(10) # Client is an ActiveRecord model
result = Concurrent::Maybe.from do
@example Using Maybe with a Block
maybe.value #=> “# Concurrent Rubyn[![Gem Version…”
maybe.nothing? #=> false
maybe.just? #=> true
maybe = MyFileUtils.consult(‘README.md’)
maybe.reason #=> #<Errno::ENOENT: No such file or directory @ rb_sysopen - bogus.file>
maybe.nothing? #=> true
maybe.just? #=> false
maybe = MyFileUtils.consult(‘bogus.file’)
end
end
file.close if file
ensure
return Concurrent::Maybe.nothing(ex)
rescue => ex
Concurrent::Maybe.just(file.read)
file = File.open(path, ‘r’)
def self.consult(path)
module MyFileUtils
@example Returning a Maybe from a Function
“‘
end
logger.error(result.reason) # or result.nothing
else
do_something_useful(result.value) # or result.just
if result.just?
result = MyFileUtils.consult(“data.dat”) # returns a Maybe
“`ruby
having functions return `Maybe` objects:
previous Erlang example can be duplicated in Ruby in a principled way by
`Nothing` the reason for the lack of a value is contained as well. The
the value it contains may be `nil`, which is perfectly valid. When
When `Just` it contains a value, when `Nothing` it does not. When `Just`
A `Maybe` is unambiguous with regard to whether or not it contains a value.
problems can be solved with the use of a `Maybe`.
is both expensive and usurps the normal flow of control. All of these
information pertaining to the nature of the error. Raising an exception
ambiguous because `nil` may also be a valid value. It also lacks
exception. Both of these idioms are problematic. Returning `nil` is
In Ruby we tend to return `nil` when an error occurs or else we raise an
error occurs the return value provides useful information.
empty the return value cannot be misinterpreted as an error. And when an
pattern there is no ambiguity regarding success or failure. If the file is
returns `error` and a string with an explanation of the problem. With this
success it returns the atom `ok` and the data from the file. On failure it
(similar to a ruby symbol) and a variable containing ancillary data. On
with two elements: an [atom](http://erlang.org/doc/reference_manual/data_types.html#id64134)<br>(erlang.org/doc/reference_manual/data_types.html#id69044)
In this example the standard library function `file:consult` returns a
“`
end.
{error, Reason} -> lager:error(Reason)
{ok, Terms} -> do_something_useful(Terms);
case file:consult(“data.dat”) of
“`erlang
Consider this Erlang code:
Haskell, is to return either a value or an error from a function
A common pattern in languages with pattern matching, such as Erlang and
## Motivation
`reason`.
accessor methods are aliased as `fulfilled?`, `rejected?`, `value`, and
For compatibility with {Concurrent::Concern::Obligation} the predicate and
`Maybe` is a replacement for the use of `nil` with better type checking.
resorting to drastic measures such as exceptions.
`Maybe` is a good way to deal with errors or exceptional cases without
of (represented as `Just`), or it is empty (represented as `Nothing`). Using
A `Maybe` encapsulates an optional value. A `Maybe` either contains a value

def self.from(*args)

Raises:
  • (ArgumentError) - when no block given.

Returns:
  • (Maybe) - The newly created object.

Other tags:
    Yieldparam: args - Zero or more block arguments passed as

Other tags:
    Yield: - The block from which to create a new `Maybe`.

Parameters:
  • args (Array) -- Zero or more arguments to pass to the block.
    def self.from(*args)
      raise ArgumentError.new('no block given') unless block_given?
      begin
        value = yield(*args)
        return new(value, NONE)
      rescue => ex
        return new(NONE, ex)
      end
    end

    def self.just(value)

    Returns:
    • (Maybe) - The newly created object.

    Parameters:
    • value (Object) -- The value to set for the new `Maybe` object.
    def self.just(value)
      return new(value, NONE)
    end

    def self.nothing(error = '')

    Returns:
    • (Maybe) - The newly created object.

    Parameters:
    • error (Exception) -- The reason to set for the new `Maybe` object.
    def self.nothing(error = '')
      if error.is_a?(Exception)
        nothing = error
      else
        nothing = StandardError.new(error.to_s)
      end
      return new(NONE, nothing)
    end

    def <=>(other)

    Returns:
    • (Integer) - 0 if self and other are both `Nothing`;
    def <=>(other)
      if nothing?
        other.nothing? ? 0 : -1
      else
        other.nothing? ? 1 : just <=> other.just
      end
    end

    def initialize(just, nothing)

    Returns:
    • (Maybe) - The new `Maybe`.

    Parameters:
    • nothing (Exception, Object) -- The exception when `Nothing` else `NONE`.
    • just (Object) -- The value when `Just` else `NONE`.
    def initialize(just, nothing)
      @just = just
      @nothing = nothing
    end

    def just?

    Returns:
    • (Boolean) - True if `Just` or false if `Nothing`.
    def just?
      ! nothing?
    end

    def nothing?

    Returns:
    • (Boolean) - True if `Nothing` or false if `Just`.
    def nothing?
      @nothing != NONE
    end

    def or(other)

    Returns:
    • (Object) - The value of self when `Just`; else the given default.
    def or(other)
      just? ? just : other
    end