xotl.tools.fp.option - Functional Programming Option Type

Functional Programming Option Type definition.

In Programming, and Type Theory, an option type, or maybe type, represents encapsulation of an optional value; e.g., it is used in functions which may or may not return a meaningful value when they are applied.

It consists of either a constructor encapsulating the original value x (written Just x or Some x) or an empty constructor (called None or Nothing). Outside of functional programming, these are known as nullable types.

In our case option type will be the Maybe class (the equivalent of Option in Scala Programming Language), the wrapper for valid values will be the Just class (equivalent of Some in Scala); and the wrapper for invalid values will be the Wrong class.

Instead of None or Nothing, Wrong is used because two reasons: (1) already existence of None special Python value, and (2) Wrong also wraps incorrect values and can have several instances (not only a null value).

class xotl.tools.fp.option.Just(*args)[source]

A wrapper for valid results.

class xotl.tools.fp.option.Maybe(*args)[source]

Wrapper for optional values.

The Maybe type encapsulates an optional value. A value of type Maybe a either contains a value of type a (represented as Just a), or it is empty (represented as Nothing). Using Maybe` is a good way to deal with errors or exceptional cases without resorting to drastic measures such as error. In this implementation we make a variation where a Wrong object represents a missing (with special value Nothing) or an improper value (including errors).

See descendant classes Just and Wrong for more information.

This implementation combines Maybe and Either Haskell data types. Maybe is a means of being explicit that you are not sure that a function will be successful when it is executed. Conventionally, the usage of Either for errors uses Right when the computation is successful, and Left for failing scenarios.

In this implementation, Just:class` us used for equivalence with both Haskell Just and Right types; Wrong is used with the special value Nothing and to encapsulate errors or incorrect values (Haskell Left).

Haskell:

data Maybe a = Nothing | Just a

either :: (a -> c) -> (b -> c) -> Either a b -> c

Case analysis for the Either type. If the value is Left a, apply the first function to a; if it is Right b, apply the second function to b.

classmethod choose(*types)[source]

Decorator to force Maybe values constraining to expecting types.

For example, a function that return a collection (tuple or list) if valid or False if not, if not decorated could be ambiguous for an empty collection:

>>> @Just.choose(tuple, list)
... def check_range(values, min, max):
...     if isinstance(values, (tuple, list)):
...         return [v for v in values if min <= v <= max]
...     else:
...         return False

>>> check_range(range(10), 7, 17)
[7, 8, 9]

>>> check_range(range(10), 17, 27)
Just([])

>>> check_range(set(range(10)), 7, 17)
False
classmethod compel(value)[source]

Coerce to the correspondent logical Boolean value.

Just is logically true, and Wrong is false.

For example:

>>> Just.compel([1])
[1]

>>> Just.compel([])
Just([])

>>> Wrong.compel([1])
Wrong([1])

>>> Wrong.compel([])
[]
class xotl.tools.fp.option.Wrong(*args)[source]

A wrapper for invalid results.

xotl.tools.fp.option.false = Wrong(False)

A Wrong special singleton encapsulating the False value.

xotl.tools.fp.option.none = Wrong(None)

A Wrong special singleton encapsulating the None value.

xotl.tools.fp.option.take(value)[source]

Extract a value.

xotl.tools.fp.option.true = Just(True)

A Just special singleton encapsulating the True value.

Further Notes

It could be thought that this kind of concept is useless in Python because the dynamic nature of the language, but always there are certain logic systems that need to wrap “correct” false values and “incorrect” true values.

Also, in functional programming, errors can be reasoned in a new way: more like as error values than in exception handling. Where the Maybe type expresses the failure possibility through Wrong instances encapsulating errors.

When receiving a Wrong instance encapsulating an error, and want to recover the exception propagation style -instead of continue in pure functional programming-, to re-raise the exception, instead the raise Python statement, use throw().

See https://en.wikipedia.org/wiki/Monad_%28functional_programming%29#The_Maybe_monad