fp.algebra¶
fp.algebra provides Functor, Applicative, Monad, Traversable and Monoid
interfaces. Their instances let you write generic operations over native values
such as Optional, Result and List; select the instance at each call. When
working with a single known type, you can also use its methods directly, such
as Result.map.
The algebra tutorial explains when to use map,
map2, ap, flat_map, traverse and sequence through optional order values.
Functor, Applicative, Monad, Traversable and Monoid over native values, with explicit instances.
| Interface | Primitive operations | Meaning |
|---|---|---|
Functor |
map[I](f, value) |
Transform a payload without changing its context |
Applicative |
pure[I](value), map2_lazy[I](f, left, right) |
Introduce a payload; combine independent computations |
Monad |
flat_map[I](f, value) |
Choose the next computation from the current payload |
Traversable |
traverse[S, G](f, source) |
Visit a source shape S in an applicative context G |
Monoid |
empty[M](), combine[M](left, right) |
An identity and an associative, ordered combination |
An instance is a compile-time dictionary named at each call: there are no
runtime interface objects and no global registry. The native instances are
IdentityFamily (the bare value), OptionalFamily, ResultFamily[E] and
ListFamily, with StringMonoid and ListMonoid[A]; fp.effects adds
Reader, State, Writer and transformers. Each operation is a static method of
the instance and the functions here forward to it; its result and error types
are associated aliases of the instance, such as I.Mapped[V, F] and
I.MapError[V, F], so generic code states them directly. The derived
operations map2, ap, flatten and sequence add no execution path.
Callbacks are fixed-arity values in any receiver mode: a Unary for map,
flat_map and traverse, a Binary combiner and a Thunk right operand for
map2_lazy. map, flat_map and traverse also take native functions and
closures directly. Operations consume carriers and callbacks. A callback that
runs repeatedly, as over a List, must have a shared or exclusive receiver; a
consuming-only callback is rejected when the program compiles. Native errors
propagate with their exact types; stored Result errors remain data.
A third-party instance implements the associated types and static methods of
the interfaces it claims, receives callbacks through their contracts and calls
them with call_once or call_repeated from fp.callables; it needs no
private library code. An Applicative-only target receives list traversal
through the default collect.
The functor, monad and monoid laws hold under pure, terminating callbacks and equivalent native ownership behavior; callbacks with effects have a specified call order and count instead.
Summary¶
| Name | Kind | Summary |
|---|---|---|
ap |
function | Apply the callbacks a carrier holds to the values another carrier holds. |
combine |
function | Combine two values with the monoid's associative, ordered combination. |
empty |
function | The monoid's identity element. |
flat_map |
function | Let f choose the next carrier of the same family from the payload of value: the Monad operation. |
flatten |
function | Remove one level of the same context: flat_map with the identity. |
map |
function | Apply f to the payload of value, keeping the carrier's context: the Functor operation. |
map2 |
function | Combine two carriers with f, where the right one is already computed. |
map2_lazy |
function | Combine the payload of left with that of the carrier right produces. |
pure |
function | Introduce a value in the instance's neutral context: the Applicative unit. |
sequence |
function | Turn a source of G carriers into one G carrier of the source: traverse with the identity. |
traverse |
function | Call an effectful f on each element of source, in order, and gather the results in one G carrier. |
IdentityFamily |
struct | The bare value as a carrier: every operation applies its callback once. |
ListFamily |
struct | The standard List as a carrier: operations run left to right, and combination is Cartesian. |
ListMonoid |
struct | List concatenation, with the empty list as identity; elements are moved, never copied. |
OptionalFamily |
struct | The standard Optional as a carrier: an absent value skips callbacks and right operands. |
ResultFamily |
struct | Result[A, E] as a carrier for a fixed stored error type E: a stored error skips callbacks and stays data. |
StringMonoid |
struct | String concatenation, with the empty string as identity. |
Applicative |
trait | A Functor that can introduce a payload (pure) and combine independent computations (map2_lazy). |
Functor |
trait | A carrier family whose payload can be transformed without changing its context: map. |
Monad |
trait | An Applicative whose callback chooses the next computation from the current payload: flat_map. |
Monoid |
trait | An identity element and an associative, ordered combination: Writer logs use one. |
Traversable |
trait | A source shape whose elements can be visited with an effectful callback, keeping the shape: traverse. |
Functions¶
ap¶
Source: fp/algebra/_derived.mojo
def ap[V, W, //, I: Applicative](
var functions: V,
var values: W,
) raises I.CombineError[V, _Apply[_Function[I, V]], _Value[W]] -> I.Combined[V, _Apply[_Function[I, V]], _Value[W]]
Apply the callbacks a carrier holds to the values another carrier holds.
Parameters
V(Movable & Deinitable, inferred): The type of the carrier of callbacks, which are libraryUnaryvalues.W(Movable & Deinitable, inferred): The type of the carrier of values.I(Applicative): The instance.
Arguments
functions(var V): The carrier of callbacks, consumed.values(var W): The carrier of values, consumed.
Returns
I.Combined[...]: The carrier of the results; for lists, every callback applied to every
value in left-major order.
Raises
I.CombineError[...]: The callbacks' error.
combine¶
Source: fp/algebra/operations.mojo
def combine[M: Monoid](
var left: M.Value,
var right: M.Value,
) raises M.Error -> M.Value
Combine two values with the monoid's associative, ordered combination.
Parameters
M(Monoid): The monoid.
Arguments
left(var M.Value): The first value, consumed.right(var M.Value): The second value, consumed.
Returns
M.Value: M.combine(left, right).
Raises
M.Error: M.Error; nothing for the library's monoids.
empty¶
Source: fp/algebra/operations.mojo
def empty[M: Monoid]() raises M.Error -> M.Value
The monoid's identity element.
Parameters
M(Monoid): The monoid, such asStringMonoid.
Returns
M.Value: M.empty().
Raises
M.Error: M.Error; nothing for the library's monoids.
flat_map¶
Source: fp/algebra/operations.mojo
def flat_map[V, F: UnaryContract & Movable & Deinitable, //, I: Monad](
var f: F,
var value: V,
) raises I.BindError[V, F] -> I.Bound[V, F]
Let f choose the next carrier of the same family from the payload of value: the Monad operation.
An absent Optional, a failed Result or an empty List skips the
callback.
Another overload takes a native function or closure directly, for every
instance: flat_map[OptionalFamily](halve, value^). It is borrowed, not moved:
an eager instance calls it before returning, and a deferred computation
keeps the borrow until it runs, so keep the callback alive and unmoved
until then, or move it in with as_unary(f^). Its parameter type must
equal the carrier's element type, origins included. Generic code that
forwards a raising native callback names its error with X=.
Parameters
V(Movable & Deinitable, inferred): The carrier's type.F(UnaryContract & Movable & Deinitable, inferred): The callback's type: a libraryUnaryvalue returning a carrier of the same family.I(Monad): The instance.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
I.Bound[V, F]: I.Bound[V, F], the carrier the callback returned.
Raises
I.BindError[V, F]: I.BindError[V, F]: the callback's error, unchanged.
2 more overloads
Let a native function or closure choose the next carrier.
def flat_map[V, A, R, o: ImmOrigin, //, I: Monad, F: _Unary[A, R]](
ref[o] f: F,
var value: V,
) raises I.BindError[V, _ErrorProbe[A, R, Never]] -> I.Bound[V, _NativeUnaryRef[A, R, Never, F, False, o]] where I.Element[V] == A
Raising form of the native flat_map; its error type is kept.
def flat_map[
V, A, R, E, o: ImmOrigin, //, I: Monad, F: _RaisingUnary[A, R, E], X:
AnyType = _InferError,
](
ref[o] f: F,
var value: V,
) raises _EntryError[X, I.BindError[V, _ErrorProbe[A, R, E]]] -> I.Bound[V, _NativeUnaryRef[A, R, E, F, True, o]] where (I.Element[V] == A and (X == _InferError or X == E))
flatten¶
Source: fp/algebra/_derived.mojo
def flatten[V, //, I: Monad](
var nested: V,
) raises I.BindError[V, _Same[I.Element[V]]] -> I.Bound[V, _Same[I.Element[V]]]
Remove one level of the same context: flat_map with the identity.
Parameters
V(Movable & Deinitable, inferred): The nested carrier's type, such asOptional[Optional[A]].I(Monad): The instance.
Arguments
nested(var V): The nested carrier, consumed.
Returns
I.Bound[...]: The inner carrier, or the outer context when there is no payload.
Raises
I.BindError[...]: The instance's bind error; the identity callback itself raises nothing.
map¶
Source: fp/algebra/operations.mojo
def map[V, F: UnaryContract & Movable & Deinitable, //, I: Functor](
var f: F,
var value: V,
) raises I.MapError[V, F] -> I.Mapped[V, F]
Apply f to the payload of value, keeping the carrier's context: the Functor operation.
Another overload takes a native function or closure directly, for every
instance: map[OptionalFamily](twice, value^). It is borrowed, not moved:
an eager instance calls it before returning, and a deferred computation
keeps the borrow until it runs, so keep the callback alive and unmoved
until then, or move it in with as_unary(f^). Its parameter type must
equal the carrier's element type, origins included. Generic code that
forwards a raising native callback names its error with X=.
Parameters
V(Movable & Deinitable, inferred): The carrier's type.F(UnaryContract & Movable & Deinitable, inferred): The callback's type: a libraryUnaryvalue in any receiver mode.I(Functor): The instance, such asOptionalFamilyorReaderT[M, R].
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
I.Mapped[V, F]: The carrier of the callback's results, I.Mapped[V, F].
Raises
I.MapError[V, F]: I.MapError[V, F]: the callback's error, unchanged.
2 more overloads
Apply a native function or closure to each element of `value`.
def map[V, A, R, o: ImmOrigin, //, I: Functor, F: _Unary[A, R]](
ref[o] f: F,
var value: V,
) raises I.MapError[V, _ErrorProbe[A, R, Never]] -> I.Mapped[V, _NativeUnaryRef[A, R, Never, F, False, o]] where I.Element[V] == A
Apply a raising native callback; its error type is kept.
def map[
V, A, R, E, o: ImmOrigin, //, I: Functor, F: _RaisingUnary[A, R, E], X:
AnyType = _InferError,
](
ref[o] f: F,
var value: V,
) raises _EntryError[X, I.MapError[V, _ErrorProbe[A, R, E]]] -> I.Mapped[V, _NativeUnaryRef[A, R, E, F, True, o]] where (I.Element[V] == A and (X == _InferError or X == E))
map2¶
Source: fp/algebra/_derived.mojo
def map2[V, W, F: BinaryContract & Movable & Deinitable, //, I: Applicative](
var f: F,
var left: V,
var right: W,
) raises I.CombineError[V, F, _Value[W]] -> I.Combined[V, F, _Value[W]]
Combine two carriers with f, where the right one is already computed.
It is map2_lazy with a right operand that returns right.
Parameters
V(Movable & Deinitable, inferred): The left carrier's type.W(Movable & Deinitable, inferred): The right carrier's type.F(BinaryContract & Movable & Deinitable, inferred): The combiner's type: a libraryBinaryvalue.I(Applicative): The instance.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var W): The right carrier, consumed.
Returns
I.Combined[...]: The carrier of the combined payloads.
Raises
I.CombineError[...]: The combiner's error.
map2_lazy¶
Source: fp/algebra/operations.mojo
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, R: ThunkContract & Movable &
Deinitable, //, I: Applicative,
](
var f: F,
var left: V,
var right: R,
) raises I.CombineError[V, F, R] -> I.Combined[V, F, R]
Combine the payload of left with that of the carrier right produces.
right runs at most once per combination, and not at all when left
already determines failure or emptiness. A produced right value is kept for
later branches; a list combines in left-major Cartesian order.
Parameters
V(Movable & Deinitable, inferred): The left carrier's type.F(BinaryContract & Movable & Deinitable, inferred): The combiner's type: a libraryBinaryvalue.R(ThunkContract & Movable & Deinitable, inferred): The right operand's type: a libraryThunkvalue producing a carrier.I(Applicative): The instance.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var R): The thunk producing the right carrier, consumed.
Returns
I.Combined[V, F, R]: I.Combined[V, F, R], the carrier of the combined payloads.
Raises
I.CombineError[V, F, R]: I.CombineError[V, F, R]: the combiner's or the thunk's error.
pure¶
Source: fp/algebra/operations.mojo
def pure[A, //, I: Applicative](var value: A) -> I.Pure[A]
Introduce a value in the instance's neutral context: the Applicative unit.
Parameters
A(Movable & Deinitable, inferred): The value's type.I(Applicative): The instance.
Arguments
value(var A): The value, consumed.
Returns
I.Pure[A]: I.Pure[A], the carrier holding value.
sequence¶
Source: fp/algebra/_derived.mojo
def sequence[V, //, S: Traversable, G: Applicative](
var source: V,
) raises S.TraverseError[G, V, _Same[S.Element[V]]] -> S.Traversed[G, V, _Same[S.Element[V]]]
Turn a source of G carriers into one G carrier of the source: traverse with the identity.
Parameters
V(Movable & Deinitable, inferred): The source's type, such asList[Optional[A]].S(Traversable): The source's instance.G(Applicative): The carriers' instance.
Arguments
source(var V): The source, consumed.
Returns
S.Traversed[...]: G's carrier of the payloads in source shape; it stops at the first
failure.
Raises
S.TraverseError[...]: Any error G adds.
traverse¶
Source: fp/algebra/operations.mojo
def traverse[
V, F: UnaryContract & Movable & Deinitable, //, S: Traversable, G:
Applicative,
](
var f: F,
var source: V,
) raises S.TraverseError[G, V, F] -> S.Traversed[G, V, F]
Call an effectful f on each element of source, in order, and gather the results in one G carrier.
The source keeps its shape. Once G has failed (an absent Optional, a
failed Result), no further element is pulled and the callback is not
called again. A List source is gathered by G.collect; any owned
iterable or iterator can be the source. Another overload takes a native
function or closure directly.
Parameters
V(Movable & Deinitable, inferred): The source's type.F(UnaryContract & Movable & Deinitable, inferred): The callback's type: a repeatable libraryUnaryvalue returning aGcarrier.S(Traversable): The source's instance, such asListFamily.G(Applicative): The callback's applicative instance, such asResultFamily[E].
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
S.Traversed[G, V, F]: S.Traversed[G, V, F], G's carrier of the results in source shape.
Raises
S.TraverseError[G, V, F]: S.TraverseError[G, V, F]: the callback's error, and any error G adds.
2 more overloads
Traverse with a native function or closure.
def traverse[
V, A, R, o: ImmOrigin, //, S: Traversable, G: Applicative, F: _Unary[A, R],
](
ref[o] f: F,
var source: V,
) raises S.TraverseError[G, V, _ErrorProbe[A, R, Never]] -> S.Traversed[G, V, _NativeUnaryRef[A, R, Never, F, False, o]] where S.Element[V] == A
Traverse with a raising native callback; its error type is kept.
def traverse[
V, A, R, E, o: ImmOrigin, //, S: Traversable, G: Applicative, F:
_RaisingUnary[A, R, E],
](
ref[o] f: F,
var source: V,
) raises S.TraverseError[G, V, _ErrorProbe[A, R, E]] -> S.Traversed[G, V, _NativeUnaryRef[A, R, E, F, True, o]] where S.Element[V] == A
Structs¶
IdentityFamily¶
Source: fp/algebra/instances.mojo
struct IdentityFamily(Monad, Traversable)
The bare value as a carrier: every operation applies its callback once.
Reader[R], State[S] and Writer[W] are their transformers over it.
Implements
Applicative, Functor, Monad, Traversable
Aliases
ElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorTraversedTraverseErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
IdentityFamily.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises BindError[V, F] -> Bound[V, F]
Apply the callback to the value; its result is the next carrier.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a carrier of the same family.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Bound[V, F]: The callback's result.
Raises
BindError[V, F]: The callback's error, unchanged.
IdentityFamily.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises MapError[V, F] -> Mapped[V, F]
Apply the callback to the value once.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Mapped[V, F]: The callback's result.
Raises
MapError[V, F]: The callback's error, unchanged.
IdentityFamily.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, R: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: R,
) raises CombineError[V, F, R] -> Combined[V, F, R]
Combine the value with the one the thunk produces.
Parameters
V(Movable & Deinitable): The left carrier's type.F(BinaryContract & Movable & Deinitable): The combiner's type.R(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a carrier.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var R): The thunk producing the right carrier, consumed.
Returns
Combined[V, F, R]: The combiner's result.
Raises
CombineError[V, F, R]: The combiner's or the thunk's error.
IdentityFamily.pure¶
def pure[A](var value: A) -> Pure[A]
Return the value itself.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The value.
IdentityFamily.traverse¶
def traverse[G: Applicative, V, F: UnaryContract & Movable & Deinitable](
var f: F,
var source: V,
) raises TraverseError[G, V, F] -> Traversed[G, V, F]
Apply the callback to the one value; its G carrier is the result.
Parameters
G(Applicative): The callback's applicative family.V(Movable & Deinitable): The source carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning aGcarrier.
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
Traversed[G, V, F]: The callback's G carrier.
Raises
TraverseError[G, V, F]: The callback's error, and any error G adds.
ListFamily¶
Source: fp/algebra/instances.mojo
struct ListFamily(Monad, Traversable)
The standard List as a carrier: operations run left to right, and combination is Cartesian.
Callbacks run once per element, so they must be repeatable: a shared or exclusive receiver.
Implements
Applicative, Functor, Monad, Traversable
Aliases
ElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorTraversedTraverseErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
ListFamily.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises BindError[V, F] -> Bound[V, F]
Concatenate the lists the callback returns for each element, left to right.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a carrier of the same family.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Bound[V, F]: The concatenated list.
Raises
BindError[V, F]: The callback's error, unchanged.
ListFamily.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises MapError[V, F] -> Mapped[V, F]
Apply the callback to each element, left to right.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Mapped[V, F]: The list of results.
Raises
MapError[V, F]: The callback's error, unchanged.
ListFamily.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, R: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: R,
) raises CombineError[V, F, R] -> Combined[V, F, R]
Combine every pair of elements, in left-major order.
The thunk runs once, and not at all for an empty left list. Elements are
copied into every pair, so both element types must be Copyable, and the
combiner must be repeatable.
Parameters
V(Movable & Deinitable): The left carrier's type.F(BinaryContract & Movable & Deinitable): The combiner's type.R(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a carrier.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var R): The thunk producing the right carrier, consumed.
Returns
Combined[V, F, R]: The list of combinations: for [a, b] and [x, y], (a, x), (a, y), (b, x), (b, y).
Raises
CombineError[V, F, R]: The combiner's or the thunk's error.
ListFamily.pure¶
def pure[A](var value: A) -> Pure[A]
A list of one element.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The one-element list.
ListFamily.traverse¶
def traverse[G: Applicative, V, F: UnaryContract & Movable & Deinitable](
var f: F,
var source: V,
) raises TraverseError[G, V, F] -> Traversed[G, V, F]
Call the callback on each element and gather the payloads with G.collect.
The first failed or absent result stops callback calls and source pulls. Any owned iterable or iterator can be the source.
Parameters
G(Applicative): The callback's applicative family.V(Movable & Deinitable): The source carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning aGcarrier.
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
Traversed[G, V, F]: G's carrier of the list of payloads.
Raises
TraverseError[G, V, F]: The callback's error, and any error G adds.
ListMonoid¶
Source: fp/algebra/monoids.mojo
struct ListMonoid[T](Monoid)
List concatenation, with the empty list as identity; elements are moved, never copied.
Parameters
T(Movable & Deinitable): The element type.
Implements
Monoid
Aliases
ValueError: The erroremptyandcombineraise;Neverby default.
ListMonoid.combine¶
def combine(var left: Value, var right: Value) -> Value
Append the elements of right to left, moving them.
Arguments
left(var Value): The first list, consumed.right(var Value): The second list, consumed.
Returns
Value: The elements of left, then those of right.
ListMonoid.empty¶
def empty() -> Value
The empty list.
Returns
Value: An empty List.
OptionalFamily¶
Source: fp/algebra/instances.mojo
struct OptionalFamily(Monad, Traversable, _Lifting)
The standard Optional as a carrier: an absent value skips callbacks and right operands.
Implements
Applicative, Functor, Monad, Traversable, _Lifting
Aliases
ElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorTraversedTraverseErrorLiftedLiftErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
OptionalFamily.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises BindError[V, F] -> Bound[V, F]
Continue with the Optional the callback returns; an absent value skips the callback.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a carrier of the same family.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Bound[V, F]: The callback's Optional, or None.
Raises
BindError[V, F]: The callback's error, unchanged.
OptionalFamily.lift¶
def lift[V](var value: V) -> Lifted[V]
Wrap a value as present, for a layer over OptionalFamily.
Parameters
V(Movable & Deinitable): The base value's type.
Arguments
value(var V): The value, consumed.
Returns
Lifted[V]: The present value.
OptionalFamily.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises MapError[V, F] -> Mapped[V, F]
Apply the callback to a present value; an absent value passes through without a call.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Mapped[V, F]: The callback's result, present, or None.
Raises
MapError[V, F]: The callback's error, unchanged.
OptionalFamily.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, R: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: R,
) raises CombineError[V, F, R] -> Combined[V, F, R]
Combine two present values; an absent left value skips the thunk.
Parameters
V(Movable & Deinitable): The left carrier's type.F(BinaryContract & Movable & Deinitable): The combiner's type.R(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a carrier.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var R): The thunk producing the right carrier, consumed.
Returns
Combined[V, F, R]: The combination, present, or None when either side is absent.
Raises
CombineError[V, F, R]: The combiner's or the thunk's error.
OptionalFamily.pure¶
def pure[A](var value: A) -> Pure[A]
Wrap the value as present.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The present value.
OptionalFamily.traverse¶
def traverse[G: Applicative, V, F: UnaryContract & Movable & Deinitable](
var f: F,
var source: V,
) raises TraverseError[G, V, F] -> Traversed[G, V, F]
Call the callback on a present value and keep its payload present in G; an absent value gives G.pure(None).
Parameters
G(Applicative): The callback's applicative family.V(Movable & Deinitable): The source carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning aGcarrier.
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
Traversed[G, V, F]: G's carrier of the Optional.
Raises
TraverseError[G, V, F]: The callback's error, and any error G adds.
ResultFamily¶
Source: fp/algebra/instances.mojo
struct ResultFamily[E](Monad, Traversable, _Lifting)
Result[A, E] as a carrier for a fixed stored error type E: a stored error skips callbacks and stays data.
Its operations are the Result methods. A native error a callback raises
propagates as a native error; it never becomes the stored Err.
Parameters
E(Movable & Deinitable): The stored error type.
Implements
Applicative, Functor, Monad, Traversable, _Lifting
Aliases
ErrorElementMappedMapErrorPureCombinedCombineErrorBoundBindErrorTraversedTraverseErrorLiftedLiftErrorCollected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
ResultFamily.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises BindError[V, F] -> Bound[V, F]
Continue with the Result the callback returns; a stored error skips the callback.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a carrier of the same family.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Bound[V, F]: The callback's Result, or the stored Err.
Raises
BindError[V, F]: The callback's error, unchanged.
ResultFamily.lift¶
def lift[V](var value: V) -> Lifted[V]
Wrap a value as Ok, for a layer over ResultFamily.
Parameters
V(Movable & Deinitable): The base value's type.
Arguments
value(var V): The value, consumed.
Returns
Lifted[V]: Ok(value).
ResultFamily.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises MapError[V, F] -> Mapped[V, F]
Apply the callback to the success value; a stored error passes through without a call.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Mapped[V, F]: Ok of the callback's result, or the stored Err.
Raises
MapError[V, F]: The callback's error, unchanged.
ResultFamily.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, R: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: R,
) raises CombineError[V, F, R] -> Combined[V, F, R]
Combine two success values; a stored error on the left skips the thunk.
Parameters
V(Movable & Deinitable): The left carrier's type.F(BinaryContract & Movable & Deinitable): The combiner's type.R(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a carrier.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var R): The thunk producing the right carrier, consumed.
Returns
Combined[V, F, R]: Ok of the combination, or the first stored Err.
Raises
CombineError[V, F, R]: The combiner's or the thunk's error.
ResultFamily.pure¶
def pure[A](var value: A) -> Pure[A]
Wrap the value as Ok.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: Ok(value).
ResultFamily.traverse¶
def traverse[G: Applicative, V, F: UnaryContract & Movable & Deinitable](
var f: F,
var source: V,
) raises TraverseError[G, V, F] -> Traversed[G, V, F]
Call the callback on the success value and wrap its payload as Ok in G; a stored error gives G.pure of it.
Parameters
G(Applicative): The callback's applicative family.V(Movable & Deinitable): The source carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning aGcarrier.
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
Traversed[G, V, F]: G's carrier of the Result.
Raises
TraverseError[G, V, F]: The callback's error, and any error G adds.
StringMonoid¶
Source: fp/algebra/monoids.mojo
struct StringMonoid(Monoid)
String concatenation, with the empty string as identity.
Implements
Monoid
Aliases
ValueError: The erroremptyandcombineraise;Neverby default.
StringMonoid.combine¶
def combine(var left: Value, var right: Value) -> Value
Append right to left.
Arguments
left(var Value): The first string, consumed.right(var Value): The second string, consumed.
Returns
Value: left + right.
StringMonoid.empty¶
def empty() -> Value
The empty string.
Returns
Value: An empty String.
Traits¶
Applicative¶
Source: fp/algebra/protocols.mojo
trait Applicative(Functor)
A Functor that can introduce a payload (pure) and combine independent computations (map2_lazy).
collect gathers every payload a callback produces over a source into a
List, and list traversal into this family uses it. It is the private
_loop with an append rule: one pull loop whose accumulation rule decides
how payloads combine and when the accumulator stops being live. The default
_loop runs over pure, map and map2_lazy and stops pulling once the
accumulator has failed. It requires an accumulator type that stays the same
across steps; a family whose combination changes type overrides the private
_Looped, _LoopError and _loop with its own single loop.
Implements
Functor
Associated aliases
Pure: The carrierpurereturns for a payloadA.Combined: The carriermap2_lazyreturns.CombineError: The errormap2_lazyraises.Collected: The carriercollectreturns: this family's carrier of aList.CollectError: The errorcollectraises.
Applicative.collect¶
def collect[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var source: V,
) raises CollectError[V, F] -> Collected[V, F]
Call f on each element of source and gather the payloads into one carrier of a List.
The first failed or absent result stops both callback calls and source pulls. This is list traversal into this family.
Parameters
V(Movable & Deinitable): The source's type: an iterator or an owned iterable.F(UnaryContract & Movable & Deinitable): The callback's type, returning a carrier of this family; it must be repeatable.
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
Collected[V, F]: The carrier of the payloads, in source order.
Raises
CollectError[V, F]: The callback's error, and any error the family's combination raises.
Applicative.map2_lazy¶
def map2_lazy[
V, F: BinaryContract & Movable & Deinitable, R: ThunkContract & Movable &
Deinitable,
](
var f: F,
var left: V,
var right: R,
) raises CombineError[V, F, R] -> Combined[V, F, R]
Combine the payloads of left and of the carrier right produces with f.
right runs zero or one times per combination: a left carrier with no
payload, such as an absent Optional, skips it.
Parameters
V(Movable & Deinitable): The left carrier's type.F(BinaryContract & Movable & Deinitable): The combiner's type, taking the two payloads.R(ThunkContract & Movable & Deinitable): The right operand's type: a thunk producing a carrier of this family.
Arguments
f(var F): The combiner, consumed.left(var V): The left carrier, consumed.right(var R): The thunk producing the right carrier, consumed.
Returns
Combined[V, F, R]: The carrier of the combined payloads.
Raises
CombineError[V, F, R]: The combiner's or the thunk's error.
Applicative.pure¶
def pure[A](var value: A) -> Pure[A]
Introduce a payload in the family's neutral context.
Parameters
A(Movable & Deinitable): The payload type.
Arguments
value(var A): The payload, consumed.
Returns
Pure[A]: The carrier holding value.
Functor¶
Source: fp/algebra/protocols.mojo
trait Functor
A carrier family whose payload can be transformed without changing its context: map.
Associated aliases
Element: The payload type of a carrierVof this family.Mapped: The carriermapreturns for a carrierVand a callbackF.MapError: The errormapraises for a carrierVand a callbackF.
Functor.map¶
def map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises MapError[V, F] -> Mapped[V, F]
Transform the payload of value with f, keeping its context.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Mapped[V, F]: The carrier of the callback's results.
Raises
MapError[V, F]: The callback's error, and any error the family adds.
Monad¶
Source: fp/algebra/protocols.mojo
trait Monad(Applicative)
An Applicative whose callback chooses the next computation from the current payload: flat_map.
A deferred family that is a transformer base also overrides the private
_Joined[L, R], _join_left and _join_right: one carrier type holding
either of two computations of this family, which a transformer step that
returns one of two computations uses. The default serves eager families,
whose carriers of one payload already share one type.
Implements
Applicative, Functor
Associated aliases
Bound: The carrierflat_mapreturns: the callback's own carrier type.BindError: The errorflat_mapraises.
Monad.flat_map¶
def flat_map[V, F: UnaryContract & Movable & Deinitable](
var f: F,
var value: V,
) raises BindError[V, F] -> Bound[V, F]
Continue with the carrier f returns for the payload of value.
Parameters
V(Movable & Deinitable): The carrier's type.F(UnaryContract & Movable & Deinitable): The callback's type, returning a carrier of this family.
Arguments
f(var F): The callback, consumed.value(var V): The carrier, consumed.
Returns
Bound[V, F]: The carrier the callback returned, or the original context when
there is no payload.
Raises
BindError[V, F]: The callback's error.
Monoid¶
Source: fp/algebra/protocols.mojo
trait Monoid
An identity element and an associative, ordered combination: Writer logs use one.
Associated aliases
Value: The combined values' type.Error: The erroremptyandcombineraise;Neverby default.
Monoid.combine¶
def combine(var left: Value, var right: Value) raises Error -> Value
Combine two values, left first.
Arguments
left(var Value): The first value, consumed.right(var Value): The second value, consumed.
Returns
Value: The combination.
Raises
Error: Error; nothing when it is Never.
Monoid.empty¶
def empty() raises Error -> Value
The identity element: combining it with a value returns the value.
Returns
Value: The identity element.
Raises
Error: Error; nothing when it is Never.
Traversable¶
Source: fp/algebra/protocols.mojo
trait Traversable(Functor)
A source shape whose elements can be visited with an effectful callback, keeping the shape: traverse.
Implements
Functor
Associated aliases
Traversed: The carriertraversereturns:G's carrier of this shape.TraverseError: The errortraverseraises.
Traversable.traverse¶
def traverse[G: Applicative, V, F: UnaryContract & Movable & Deinitable](
var f: F,
var source: V,
) raises TraverseError[G, V, F] -> Traversed[G, V, F]
Call f on each element of source, in order, and gather the results into one G carrier of the same shape.
Parameters
G(Applicative): The applicative family the callback returns.V(Movable & Deinitable): The source's type, of this shape.F(UnaryContract & Movable & Deinitable): The callback's type, returning aGcarrier.
Arguments
f(var F): The callback, consumed.source(var V): The source, consumed.
Returns
Traversed[G, V, F]: G's carrier of the results, in source shape and order.
Raises
TraverseError[G, V, F]: The callback's error, and any error G adds.
Use one set of operations over four carriers¶
"""One set of operations, with explicit native context selection."""
from fp.algebra import (
map, pure, flat_map, traverse,
IdentityFamily, OptionalFamily, ResultFamily, ListFamily,
)
def twice(var value: Int) -> Int:
return value * 2
def positive(var value: Int) -> Optional[Int]:
return Optional(value) if value > 0 else Optional[Int]()
def main() raises:
# The same mapper preserves each context's native representation.
print("identity:", map[IdentityFamily](twice, 3))
print("optional:", map[OptionalFamily](twice, Optional(3)).value())
var checked = map[ResultFamily[Error]](twice, pure[ResultFamily[Error]](3))
print("result:", checked^.raise_on_err())
var values: List[Int] = [1, 2, 3]
var doubled = map[ListFamily](twice, values^)
print("list:", doubled[0], doubled[1], doubled[2])
# flat_map lets the callback choose the next computation in that context.
var absent = flat_map[OptionalFamily](positive, Optional(-1))
print("positive -1 present:", Bool(absent))
# Traverse collects the same source shape, or stops at the first absence.
var valid: List[Int] = [1, 2, 3]
var accepted = traverse[ListFamily, OptionalFamily](positive, valid^)
print("traversed:", len(accepted.value()))
var invalid: List[Int] = [1, -2, 3]
var rejected = traverse[ListFamily, OptionalFamily](positive, invalid^)
print("invalid traversal present:", Bool(rejected))
Run from the repository root pixi run mojo run -I src docs/examples/algebra_core.mojo
Output
identity: 6
optional: 6
result: 6
list: 2 4 6
positive -1 present: False
traversed: 3
invalid traversal present: False
map[I](twice, ...) doubles 3 to 6 as a bare value, inside an Optional
and inside a Result, and doubles [1, 2, 3] to 2 4 6; each result keeps its
native type. flat_map[OptionalFamily](positive, Optional(-1)) lets positive
return an absent value. traverse[ListFamily, OptionalFamily](positive, ...)
returns a present list of three values for [1, 2, 3], and an absent value
for [1, -2, 3], stopping at -2.