Monad#
Meme
A monad is a monoid in the category of endofunctors.
Monadic interfaces that enable structured ways to compose and manipulate computations on a single effectful construction.
The module defines three abstract classes: Functor,
Applicative, and Monad.
Rationale#
Monadic abstractions like Functor, Applicative, and Monad are popularized by Haskell.
Although Python has weak support for functional programming, we include these abstractions to provide a uniform interface for such calculations.
Under the hood, these abstractions use dynamic single dispatch provided in apfel.core.dispatch, which
allows us to define monadic helper functions for standard built-in types.
This module provides default implementations for list, tuple, set, and function as Functor, Applicative, and Monad, dict as Functor.
Note that we losen the constraints of such abstractions, as writing pure functional code is not a goal of this library.
Usage#
Here's a high-level comparison of the three.
Assume Value is a Monad.
A Monad is always a Functor and an Applicative.
value = Value(42)
assert value.map ( lambda x: x + 1 ) == Value(43)
assert value.apply(Value(lambda x: x + 1)) == Value(43)
assert value.bind (lambda x: Value(x + 1)) == Value(43)
If you are familiar with Rust,
Option is a Monad,
Option.map is its Functor.map,
Option.and_then is its Monad.bind.
Case: list#
assert Functor.map([1, 2, 3], lambda x: x + 1) == [2, 3, 4]
assert Applicative.apply([1, 2, 3], [lambda x: x + 1, lambda x: x + 2]) == [2, 3, 4, 3, 4, 5]
assert Monad.bind([1, 2, 3], lambda x: [x, x + 1]) == [1, 2, 2, 3, 3, 4]
Case: function#
Functor.map of a function is exactly a composition of functions.
Functor
#
A functor is a type that can apply a function to its inner value(s) without changing its structure.
To implement a Functor, you need to implement at least the map method.
See Functor for more information.
map(f)
abstractmethod
#
Apply a function to the inner value(s) of the functor, returning a new
instance of the functor.
This corresponds to the fmap in Haskell.
Built-in map function
returns an iterator, not a new instance of the functor.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Callable[[T], R]
|
The function to apply. |
required |
Returns:
| Type | Description |
|---|---|
Functor[R]
|
A new instance of the functor with transformed inner value(s). |
Applicative
#
An applicative functor is a functor extended with the ability to apply an effectful function to its inner value(s).
To implement an Applicative, you need to implement at least the pure and apply methods.
See Applicative for more information.
apply(f)
abstractmethod
#
Applies a function wrapped inside the applicative structure to the inner value(s) of this applicative.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Applicative[Callable[[T], R]]
|
The applicative that contains the function to apply. |
required |
Returns:
| Type | Description |
|---|---|
Applicative[R]
|
A new instance of the applicative with the transformed inner value(s). |
pure(x)
abstractmethod
classmethod
#
Monad
#
A monad is an applicative functor extended with the ability to reuse results of previous computations and chain effectful computations together.
To implement a Monad, you need to implement at least the bind method, and
the pure method from Applicative.
See Monad for more information.
Notes
return is a reserved keyword in Python, and Haskell return is a historical mistake that is now
pointing to pure.
bind(f)
abstractmethod
#
Chain a new monadic computation to the current one.
The argument f maps a pure value of the monad's inner type to the monadic value.
bind chains this computation to the one it represents.
If its computation fails, the following computations will not be executed.
The function f is called a Kleisli arrow.
This bind operation has other names in different programming languages.
For example, in Option monad, it is called and_then.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f
|
Callable[[T], Monad[R]]
|
The function that returns a new monadic computation. |
required |
Returns:
| Type | Description |
|---|---|
Monad[R]
|
A new instance of the monad with the result of the chained computation. |
fmap = Functor.map
module-attribute
#
An alias for Functor.map.