fp.functions¶
fp.functions provides eager pipelines, function composition and partial
application. Use pipe to apply a sequence of functions now, flow or compose
to build a function for later calls, and partial to bind leading arguments.
The pipeline tutorial starts with a complete program.
Pipelines, compositions, argument flipping and partial application.
Use pipe(value, f, g) to apply stages now, flow(f, g) or compose(g, f) to
build a reusable composition, and piped(value).then(f).get() to chain any
number of stages one call at a time. flip swaps two arguments and partial
binds leading arguments.
A stage is a plain function, a closure promoted with as_unary, or a library
value that implements Unary, such as a Partial or a Composition. Each
stage's input must equal the previous stage's result. Values move from stage to
stage without copies, stages are borrowed, and a raised error stops the chain
with its own type; a returned Result is ordinary data.
Summary¶
| Name | Kind | Summary |
|---|---|---|
compose |
function | Compose stages right to left; nothing runs until the result is called. |
flip |
function | Swap the two arguments of a binary callable, keeping its receiver modes. |
flow |
function | Compose stages left to right; nothing runs until the result is called. |
identity |
function | Return value unchanged, moving it. |
partial |
function | Bind a plain function's first argument; call the result with the rest. |
pipe |
function | Apply stages to value left to right and return the last result. |
piped |
function | Start an eager chained pipeline: piped(value).then(f).then(g).get(). |
Composition |
struct | A stored chain of stages, returned by flow and compose. |
Flipped |
struct | A binary callable called with its two arguments swapped, returned by flip. |
FlippedFunction |
struct | A plain function called with its first two arguments swapped, returned by flip. |
Identity |
struct | The unary identity on T, returned by flow[T]() and compose[T](). |
Partial |
struct | A plain function with copies of its leading arguments, returned by partial. |
Piped |
struct | A value in an eager chained pipeline, started by piped(value). |
as_unary |
re-export | Re-exported from fp.callables. |
Functions¶
compose¶
Source: fp/functions/composition.mojo
def compose[*Fs](
var *functions: *Fs,
) -> Composition[True, _Arity[Fs[Fs.length - 1]], *Fs] where Fs.length >= 2
Compose stages right to left; nothing runs until the result is called.
compose(h, g, f)(x) is h(g(f(x))): the last argument runs first and may
take zero, one or two arguments. Plain functions, library values and
promoted closures are accepted as in flow. A mismatched stage is reported
by its position in the run order and its argument position.
Limitations
At most eight plain functions per call, and plain functions mixed with
library values are promoted with as_unary, as in pipe.
Parameters
*Fs(Movable & Deinitable): The stage types, in the order they are passed.
Arguments
*functions(var *Fs): The stages, moved into the composition.
Returns
Composition[...]: A Composition that runs the stages right to left.
23 more overloads
Return the identity on `T`: a composition with no stages.
def compose[T]() -> Identity[T]
Return one stage unchanged, with all its capabilities.
def compose[F](var function: F) -> F
Store 2 plain functions, applied right to left.
def compose[A0, A1, A2, P1, E0, E1, //](
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 3 plain functions, applied right to left.
def compose[A0, A1, A2, A3, P1, P2, E0, E1, E2, //](
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 4 plain functions, applied right to left.
def compose[A0, A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 5 plain functions, applied right to left.
def compose[A0, A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 6 plain functions, applied right to left.
def compose[
A0, A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5, //,
](
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 7 plain functions, applied right to left.
def compose[
A0, A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3, E4,
E5, E6, //,
](
f6: def(var P6) raises E6 thin -> A7,
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P6, A7, E6], _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 8 plain functions, applied right to left.
def compose[
A0, A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1, E2,
E3, E4, E5, E6, E7, //,
](
f7: def(var P7) raises E7 thin -> A8,
f6: def(var P6) raises E6 thin -> A7,
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var A0) raises E0 thin -> A1,
) -> Composition[True, 1, _Thin1F[P7, A8, E7], _Thin1F[P6, A7, E6], _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin1F[A0, A1, E0]]
Store 2 plain functions, applied right to left.
def compose[A1, A2, P1, E0, E1, //](
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 3 plain functions, applied right to left.
def compose[A1, A2, A3, P1, P2, E0, E1, E2, //](
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 4 plain functions, applied right to left.
def compose[A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 5 plain functions, applied right to left.
def compose[A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 6 plain functions, applied right to left.
def compose[
A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5, //,
](
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 7 plain functions, applied right to left.
def compose[
A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3, E4, E5,
E6, //,
](
f6: def(var P6) raises E6 thin -> A7,
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P6, A7, E6], _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 8 plain functions, applied right to left.
def compose[
A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1, E2, E3,
E4, E5, E6, E7, //,
](
f7: def(var P7) raises E7 thin -> A8,
f6: def(var P6) raises E6 thin -> A7,
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def() raises E0 thin -> A1,
) -> Composition[True, 0, _Thin1F[P7, A8, E7], _Thin1F[P6, A7, E6], _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin0F[A1, E0]]
Store 2 plain functions, applied right to left.
def compose[B0, B1, A1, A2, P1, E0, E1, //](
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
Store 3 plain functions, applied right to left.
def compose[B0, B1, A1, A2, A3, P1, P2, E0, E1, E2, //](
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
Store 4 plain functions, applied right to left.
def compose[B0, B1, A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
Store 5 plain functions, applied right to left.
def compose[B0, B1, A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
Store 6 plain functions, applied right to left.
def compose[
B0, B1, A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5,
//,
](
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
Store 7 plain functions, applied right to left.
def compose[
B0, B1, A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3,
E4, E5, E6, //,
](
f6: def(var P6) raises E6 thin -> A7,
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P6, A7, E6], _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
Store 8 plain functions, applied right to left.
def compose[
B0, B1, A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1,
E2, E3, E4, E5, E6, E7, //,
](
f7: def(var P7) raises E7 thin -> A8,
f6: def(var P6) raises E6 thin -> A7,
f5: def(var P5) raises E5 thin -> A6,
f4: def(var P4) raises E4 thin -> A5,
f3: def(var P3) raises E3 thin -> A4,
f2: def(var P2) raises E2 thin -> A3,
f1: def(var P1) raises E1 thin -> A2,
f0: def(var B0, var B1) raises E0 thin -> A1,
) -> Composition[True, 2, _Thin1F[P7, A8, E7], _Thin1F[P6, A7, E6], _Thin1F[P5, A6, E5], _Thin1F[P4, A5, E4], _Thin1F[P3, A4, E3], _Thin1F[P2, A3, E2], _Thin1F[P1, A2, E1], _Thin2F[B0, B1, A1, E0]]
flip¶
Source: fp/functions/flipped.mojo
def flip[F: BinaryContract & Movable & Deinitable](
var function: F,
) -> Flipped[F]
Swap the two arguments of a binary callable, keeping its receiver modes.
Parameters
F(BinaryContract & Movable & Deinitable): The callable's type, aBinary,MutableBinaryorOnceBinary.
Arguments
function(var F): The binary library value to flip, moved in.
Returns
Flipped[F]: A Flipped that calls function(second, first).
def flip[A0, A1, R, E, Rs: TypeList[Trait=_Swap, ...], //](
function: def(var a0: A0, var a1: A1, *args: *Rs) raises E thin -> R,
) -> FlippedFunction[R, E, A0, A1, Rs]
Swap the first two arguments of a plain function.
flip(f)(a, b, rest...) calls f(b, a, rest...) and keeps f's error type.
Limitations
f must be a plain function (no captures); flip a closure by writing
another closure. Keyword arguments are not forwarded.
Parameters
A0(Movable & Deinitable, inferred): The function's first parameter type.A1(Movable & Deinitable, inferred): The function's second parameter type.R(Movable & Deinitable, inferred): The function's result type.E(Movable & Deinitable, inferred): The function's error type,Neverfor a pure function.Rs(TypeList[...], inferred): The types of the remaining parameters.
Arguments
function(def(var a0: A0, var a1: A1, *args: *Rs) raises E thin -> R): The plain function to flip.
Returns
FlippedFunction[R, E, A0, A1, Rs]: A FlippedFunction that calls function(second, first, rest...).
flow¶
Source: fp/functions/composition.mojo
def flow[*Fs](
var *functions: *Fs,
) -> Composition[False, _Arity[Fs[0]], *Fs] where Fs.length >= 2
Compose stages left to right; nothing runs until the result is called.
flow(f, g, h)(x) is h(g(f(x))). Two to eight plain functions are accepted
as they are; library values such as partials, compositions and flipped
functions, and closures promoted with as_unary, are accepted in any
number. The first stage may take zero, one or two arguments; every later
stage takes the previous result, or the call does not compile, with an
error that names the stage.
Limitations
At most eight plain functions per call, and plain functions mixed with
library values are promoted with as_unary, as in pipe.
Parameters
*Fs(Movable & Deinitable): The stage types.
Arguments
*functions(var *Fs): The stages, moved into the composition.
Returns
Composition[...]: A Composition that runs the stages left to right.
23 more overloads
Return the identity on `T`: a composition with no stages.
def flow[T]() -> Identity[T]
Return one stage unchanged, with all its capabilities.
def flow[F](var function: F) -> F
Store 2 plain functions, applied left to right.
def flow[A0, A1, A2, P1, E0, E1, //](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1]]
Store 3 plain functions, applied left to right.
def flow[A0, A1, A2, A3, P1, P2, E0, E1, E2, //](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2]]
Store 4 plain functions, applied left to right.
def flow[A0, A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3]]
Store 5 plain functions, applied left to right.
def flow[A0, A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4]]
Store 6 plain functions, applied left to right.
def flow[
A0, A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5, //,
](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5]]
Store 7 plain functions, applied left to right.
def flow[
A0, A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3, E4,
E5, E6, //,
](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5], _Thin1F[P6, A7, E6]]
Store 8 plain functions, applied left to right.
def flow[
A0, A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1, E2,
E3, E4, E5, E6, E7, //,
](
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
f7: def(var P7) raises E7 thin -> A8,
) -> Composition[False, 1, _Thin1F[A0, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5], _Thin1F[P6, A7, E6], _Thin1F[P7, A8, E7]]
Store 2 plain functions, applied left to right.
def flow[A1, A2, P1, E0, E1, //](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1]]
Store 3 plain functions, applied left to right.
def flow[A1, A2, A3, P1, P2, E0, E1, E2, //](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2]]
Store 4 plain functions, applied left to right.
def flow[A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3]]
Store 5 plain functions, applied left to right.
def flow[A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4]]
Store 6 plain functions, applied left to right.
def flow[
A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5, //,
](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5]]
Store 7 plain functions, applied left to right.
def flow[
A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3, E4, E5,
E6, //,
](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5], _Thin1F[P6, A7, E6]]
Store 8 plain functions, applied left to right.
def flow[
A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1, E2, E3,
E4, E5, E6, E7, //,
](
f0: def() raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
f7: def(var P7) raises E7 thin -> A8,
) -> Composition[False, 0, _Thin0F[A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5], _Thin1F[P6, A7, E6], _Thin1F[P7, A8, E7]]
Store 2 plain functions, applied left to right.
def flow[B0, B1, A1, A2, P1, E0, E1, //](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1]]
Store 3 plain functions, applied left to right.
def flow[B0, B1, A1, A2, A3, P1, P2, E0, E1, E2, //](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2]]
Store 4 plain functions, applied left to right.
def flow[B0, B1, A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3]]
Store 5 plain functions, applied left to right.
def flow[B0, B1, A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4]]
Store 6 plain functions, applied left to right.
def flow[
B0, B1, A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5,
//,
](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5]]
Store 7 plain functions, applied left to right.
def flow[
B0, B1, A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3,
E4, E5, E6, //,
](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5], _Thin1F[P6, A7, E6]]
Store 8 plain functions, applied left to right.
def flow[
B0, B1, A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1,
E2, E3, E4, E5, E6, E7, //,
](
f0: def(var B0, var B1) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
f7: def(var P7) raises E7 thin -> A8,
) -> Composition[False, 2, _Thin2F[B0, B1, A1, E0], _Thin1F[P1, A2, E1], _Thin1F[P2, A3, E2], _Thin1F[P3, A4, E3], _Thin1F[P4, A5, E4], _Thin1F[P5, A6, E5], _Thin1F[P6, A7, E6], _Thin1F[P7, A8, E7]]
identity¶
Source: fp/functions/pipeline.mojo
def identity[T: Movable](var value: T) -> T
Return value unchanged, moving it.
Parameters
T(Movable): The value's type.
Arguments
value(var T): The value, consumed.
Returns
T: value itself; nothing is copied.
partial¶
Source: fp/functions/partial.mojo
def partial[A0: _Bound, R, E, Rs: TypeList[Trait=_Rest, ...], //](
function: def(var a0: A0, *args: *Rs) raises E thin -> R,
a0: A0,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0](), Rs]
Bind a plain function's first argument; call the result with the rest.
partial(f, a)(b, c) calls f(a, b, c). The overloads bind zero to eight
leading arguments, as in partial(f, a, b). Construction copies each bound
argument once and never calls f; every call passes f fresh copies, and
the remaining arguments are borrowed. The result keeps f's error type.
Limitations
f must be a plain function (no captures) whose remaining parameters
are read, not owned or mut; bound values must be Copyable; and a
Partial cannot be the target of another partial. Keyword binding,
reordering and the other cases are written as a closure.
Parameters
A0(inferred): The bound argument's type; it must beCopyable.R(Movable & Deinitable, inferred): The function's result type.E(Movable & Deinitable, inferred): The function's error type,Neverfor a pure function.Rs(TypeList[...], inferred): The types of the remaining parameters.
Arguments
function(def(var a0: A0, *args: *Rs) raises E thin -> R): The plain function.a0(A0): The value to bind, copied.
Returns
Partial[...]: A Partial that calls function(a0, rest...).
8 more overloads
Store a native function without binding arguments.
def partial[R, E, Rs: TypeList[Trait=_Rest, ...], //](
function: def(*args: *Rs) raises E thin -> R,
) -> Partial[R, E, TypeList.of[Trait=_Bound](), Rs]
Bind the first two arguments.
def partial[A0: _Bound, A1: _Bound, R, E, Rs: TypeList[Trait=_Rest, ...], //](
function: def(var a0: A0, var a1: A1, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1](), Rs]
Bind the first three arguments.
def partial[
A0: _Bound, A1: _Bound, A2: _Bound, R, E, Rs: TypeList[Trait=_Rest, ...],
//,
](
function: def(var a0: A0, var a1: A1, var a2: A2, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
a2: A2,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1, A2](), Rs]
Bind the first four arguments.
def partial[
A0: _Bound, A1: _Bound, A2: _Bound, A3: _Bound, R, E, Rs:
TypeList[Trait=_Rest, ...], //,
](
function: def(var a0: A0, var a1: A1, var a2: A2, var a3: A3, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
a2: A2,
a3: A3,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1, A2, A3](), Rs]
Bind the first five arguments.
def partial[
A0: _Bound, A1: _Bound, A2: _Bound, A3: _Bound, A4: _Bound, R, E, Rs:
TypeList[Trait=_Rest, ...], //,
](
function: def(var a0: A0, var a1: A1, var a2: A2, var a3: A3, var a4: A4, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
a2: A2,
a3: A3,
a4: A4,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1, A2, A3, A4](), Rs]
Bind the first six arguments.
def partial[
A0: _Bound, A1: _Bound, A2: _Bound, A3: _Bound, A4: _Bound, A5: _Bound, R,
E, Rs: TypeList[Trait=_Rest, ...], //,
](
function: def(var a0: A0, var a1: A1, var a2: A2, var a3: A3, var a4: A4, var a5: A5, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
a2: A2,
a3: A3,
a4: A4,
a5: A5,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1, A2, A3, A4, A5](), Rs]
Bind the first seven arguments.
def partial[
A0: _Bound, A1: _Bound, A2: _Bound, A3: _Bound, A4: _Bound, A5: _Bound, A6:
_Bound, R, E, Rs: TypeList[Trait=_Rest, ...], //,
](
function: def(var a0: A0, var a1: A1, var a2: A2, var a3: A3, var a4: A4, var a5: A5, var a6: A6, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
a2: A2,
a3: A3,
a4: A4,
a5: A5,
a6: A6,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1, A2, A3, A4, A5, A6](), Rs]
Bind the first eight arguments.
def partial[
A0: _Bound, A1: _Bound, A2: _Bound, A3: _Bound, A4: _Bound, A5: _Bound, A6:
_Bound, A7: _Bound, R, E, Rs: TypeList[Trait=_Rest, ...], //,
](
function: def(var a0: A0, var a1: A1, var a2: A2, var a3: A3, var a4: A4, var a5: A5, var a6: A6, var a7: A7, *args: *Rs) raises E thin -> R,
a0: A0,
a1: A1,
a2: A2,
a3: A3,
a4: A4,
a5: A5,
a6: A6,
a7: A7,
) -> Partial[R, E, TypeList.of[Trait=_Bound, A0, A1, A2, A3, A4, A5, A6, A7](), Rs]
pipe¶
Source: fp/functions/pipeline.mojo
def pipe[A, //, *Fs](
var value: A,
*functions: *Fs,
) raises _Plan[*Fs].Failure -> _PipelineResult[A, _Plan[*Fs].Results] where Fs.length >= 2
Apply stages to value left to right and return the last result.
Each stage runs once, in order, and receives the previous stage's result as
an owned value; tuples and Result values pass whole. Two to eight plain
functions are accepted as they are, pipe(value, parse, check, render);
library values such as partials and compositions, and closures promoted
with as_unary, are accepted in any number. A stage whose input is not the
previous result is a compile error that names the stage. pipe[E=Failure]
states the common error, and pipe[Results, E] every result type.
Limitations
At most eight plain functions per call, because Mojo 1.1 cannot read a
function's signature from a variadic pack: nest calls, group stages
with flow, or chain them with piped. Plain functions mixed with
library values are promoted with as_unary. Stages that raise
different error types are mapped to one type first.
Parameters
A(Movable & Deinitable, inferred): The input type.*Fs(Movable & Deinitable): The stage types.
Arguments
value(var A): The input, consumed.*functions(*Fs): The stages, borrowed, in the order they run.
Returns
The last stage's result.
Raises
The error type that every raising stage declares; a pipeline of pure stages does not raise.
13 more overloads
Return `value` unchanged: a pipeline with no stages.
def pipe[T: Movable](var value: T) -> T
Apply one pure stage: a plain function or a closure.
def pipe[A: Movable, R: Movable, //, F: def(var A) -> R](
var value: A,
function: F,
) -> R
Apply one raising stage; its error type is kept.
def pipe[A: Movable, R: Movable, E: AnyType, //, F: def(var A) raises E -> R](
var value: A,
function: F,
) raises E -> R
Apply one library `Unary` value, such as a partial or a composition.
def pipe[A, F: Unary](
var value: A,
function: F,
) raises F.Error -> F.Out where F.Arg == A
Apply stages with every result type stated: `pipe[Results, E](value, *stages)`.
def pipe[
A, //, Results: TypeList[Trait=Movable & Deinitable, ...], E: Movable &
Deinitable = Never, *Fs,
](
var value: A,
*functions: *Fs,
) raises E -> _PipelineResult[A, Results]
Apply stages with their common error stated: `pipe[E=Failure](value, *stages)`.
def pipe[A, //, E, *Fs](
var value: A,
*functions: *Fs,
) raises E -> _PipelineResult[A, _Plan[*Fs].Results] where Fs.length >= 2
Apply 2 plain functions in order.
def pipe[A0, A1, A2, P1, E0, E1, //](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
) raises _CommonError[E0, E1] -> A2
Apply 3 plain functions in order.
def pipe[A0, A1, A2, A3, P1, P2, E0, E1, E2, //](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
) raises _CommonError[_CommonError[E0, E1], E2] -> A3
Apply 4 plain functions in order.
def pipe[A0, A1, A2, A3, A4, P1, P2, P3, E0, E1, E2, E3, //](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
) raises _CommonError[_CommonError[_CommonError[E0, E1], E2], E3] -> A4
Apply 5 plain functions in order.
def pipe[A0, A1, A2, A3, A4, A5, P1, P2, P3, P4, E0, E1, E2, E3, E4, //](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
) raises _CommonError[_CommonError[_CommonError[_CommonError[E0, E1], E2], E3], E4] -> A5
Apply 6 plain functions in order.
def pipe[
A0, A1, A2, A3, A4, A5, A6, P1, P2, P3, P4, P5, E0, E1, E2, E3, E4, E5, //,
](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
) raises _CommonError[_CommonError[_CommonError[_CommonError[_CommonError[E0, E1], E2], E3], E4], E5] -> A6
Apply 7 plain functions in order.
def pipe[
A0, A1, A2, A3, A4, A5, A6, A7, P1, P2, P3, P4, P5, P6, E0, E1, E2, E3, E4,
E5, E6, //,
](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
) raises _CommonError[_CommonError[_CommonError[_CommonError[_CommonError[_CommonError[E0, E1], E2], E3], E4], E5], E6] -> A7
Apply 8 plain functions in order.
def pipe[
A0, A1, A2, A3, A4, A5, A6, A7, A8, P1, P2, P3, P4, P5, P6, P7, E0, E1, E2,
E3, E4, E5, E6, E7, //,
](
var value: A0,
f0: def(var A0) raises E0 thin -> A1,
f1: def(var P1) raises E1 thin -> A2,
f2: def(var P2) raises E2 thin -> A3,
f3: def(var P3) raises E3 thin -> A4,
f4: def(var P4) raises E4 thin -> A5,
f5: def(var P5) raises E5 thin -> A6,
f6: def(var P6) raises E6 thin -> A7,
f7: def(var P7) raises E7 thin -> A8,
) raises _CommonError[_CommonError[_CommonError[_CommonError[_CommonError[_CommonError[_CommonError[E0, E1], E2], E3], E4], E5], E6], E7] -> A8
piped¶
Source: fp/functions/pipeline.mojo
def piped[T](var value: T) -> Piped[T]
Start an eager chained pipeline: piped(value).then(f).then(g).get().
The chain returns g(f(value)). Each stage runs once, when its then is
called, so a chain has no limit on its length, and closures need no
as_unary. Unlike pipe, the stages need not share one error type: each
then raises its own.
Parameters
T(Movable & Deinitable): The input type.
Arguments
value(var T): The input, consumed.
Returns
Piped[T]: A chain holding value.
Structs¶
Composition¶
Source: fp/functions/composition.mojo
struct Composition[reverse: Bool, arity: Int, *Fs](
Movable,
Copyable where Fs.map[_Cell]().all_conforms_to[Copyable](),
ThunkContract where arity == 0,
UnaryContract where arity == 1,
BinaryContract where arity == 2,
Thunk where arity == 0 and _AllShared[Fs],
MutableThunk where arity == 0 and _AllMutable[Fs],
OnceThunk where arity == 0 and _AllOnce[Fs],
Unary where arity == 1 and _AllShared[Fs],
MutableUnary where arity == 1 and _AllMutable[Fs],
OnceUnary where arity == 1 and _AllOnce[Fs],
Binary where arity == 2 and _AllShared[Fs],
MutableBinary where arity == 2 and _AllMutable[Fs],
OnceBinary where arity == 2 and _AllOnce[Fs],
)
A stored chain of stages, returned by flow and compose.
The first stage to run may take zero, one or two arguments (a Thunk,
Unary or Binary, including plain functions and closures promoted with
as_unary); every later stage takes the previous result. Calling the
composition runs each stage once, in order, and a raised error stops it.
It is itself a Thunk, Unary or Binary in each receiver mode that all
its stages support: shared (call, __call__), exclusive (call_mut) or
consuming (call_once). Nothing runs during construction. It is Copyable
when every stage is, and copying is explicit.
Parameters
reverse(Bool): True forcompose, whose stages run right to left.arity(Int): The number of arguments the first stage takes: 0, 1 or 2.*Fs(Movable & Deinitable): The stage types, in the order they were passed.
Implements
Binary, BinaryContract, Copyable, MutableBinary, MutableThunk, MutableUnary, OnceBinary, OnceThunk, OnceUnary, Thunk, ThunkContract, Unary, UnaryContract
Aliases
CellsStageOrderedPlanArgFirstSecondOutError
Composition.__call__ { #Composition.call .api-name }¶
def __call__(self, var arg: Arg) raises Error -> Out
Run the stages on one argument, as call does.
Arguments
arg(var Arg): The first stage's argument, consumed.
Returns
Out: The last stage's result.
Raises
Error: The stages' common error; later stages do not run.
2 more overloads
Run the stages, as `call` does, when the first takes no argument.
def __call__(self) raises Error -> Out
Run the stages on two arguments, as `call` does.
def __call__(self, var first: First, var second: Second) raises Error -> Out
Composition.call¶
def call(self, var arg: Arg) raises Error -> Out
Run the stages on one argument.
Arguments
arg(var Arg): The first stage's argument, consumed.
Returns
Out: The last stage's result.
Raises
Error: The stages' common error; later stages do not run.
2 more overloads
Run the stages when the first takes no argument.
def call(self) raises Error -> Out
Run the stages on two arguments.
def call(self, var first: First, var second: Second) raises Error -> Out
Composition.call_mut¶
def call_mut(mut self, var arg: Arg) raises Error -> Out
Run the stages on one argument with exclusive access to stages that keep state.
Arguments
arg(var Arg): The first stage's argument, consumed.
Returns
Out: The last stage's result.
Raises
Error: The stages' common error; later stages do not run.
2 more overloads
Run the stages with exclusive access when the first takes no argument.
def call_mut(mut self) raises Error -> Out
Run the stages on two arguments with exclusive access.
def call_mut(mut self, var first: First, var second: Second) raises Error -> Out
Composition.call_once¶
def call_once(deinit self, var arg: Arg) raises Error -> Out
Run the stages on one argument once, consuming the composition.
Arguments
arg(var Arg): The first stage's argument, consumed.
Returns
Out: The last stage's result.
Raises
Error: The stages' common error; later stages do not run.
2 more overloads
Run the stages once, consuming them, when the first takes no argument.
def call_once(deinit self) raises Error -> Out
Run the stages on two arguments once, consuming the composition.
def call_once(
deinit self,
var first: First,
var second: Second,
) raises Error -> Out
Flipped¶
Source: fp/functions/flipped.mojo
struct Flipped[F: BinaryContract & Movable & Deinitable](
Binary where conforms_to(F, Binary),
MutableBinary where conforms_to(F, Binary) or conforms_to(F, MutableBinary),
OnceBinary,
Copyable where conforms_to(F, Copyable),
)
A binary callable called with its two arguments swapped, returned by flip.
It has the receiver modes of the callable it wraps.
Parameters
F(BinaryContract & Movable & Deinitable): The wrapped callable's type, aBinary,MutableBinaryorOnceBinary.
Implements
Binary, BinaryContract, Copyable, MutableBinary, OnceBinary
Aliases
FirstSecondOutError
Flipped.__call__ { #Flipped.call .api-name }¶
def __call__(self, var first: First, var second: Second) raises Error -> Out
Call the wrapped callable with the arguments swapped, as call does.
Arguments
first(var First): The flipped callable's first argument, passed second.second(var Second): The flipped callable's second argument, passed first.
Returns
Out: The wrapped callable's result.
Raises
Error: The wrapped callable's error, unchanged.
Flipped.call¶
def call(self, var first: First, var second: Second) raises Error -> Out
Call the wrapped callable with the arguments swapped, reading it.
Arguments
first(var First): The flipped callable's first argument, passed second.second(var Second): The flipped callable's second argument, passed first.
Returns
Out: The wrapped callable's result.
Raises
Error: The wrapped callable's error, unchanged.
Flipped.call_mut¶
def call_mut(mut self, var first: First, var second: Second) raises Error -> Out
Call the wrapped callable with the arguments swapped and exclusive access.
Arguments
first(var First): The flipped callable's first argument, passed second.second(var Second): The flipped callable's second argument, passed first.
Returns
Out: The wrapped callable's result.
Raises
Error: The wrapped callable's error, unchanged.
Flipped.call_once¶
def call_once(
deinit self,
var first: First,
var second: Second,
) raises Error -> Out
Call the wrapped callable once with the arguments swapped, consuming it.
Arguments
first(var First): The flipped callable's first argument, passed second.second(var Second): The flipped callable's second argument, passed first.
Returns
Out: The wrapped callable's result.
Raises
Error: The wrapped callable's error, unchanged.
FlippedFunction¶
Source: fp/functions/flipped.mojo
struct FlippedFunction[R, E, A0, A1, Rs: TypeList[Trait=_Swap, ...]](
Copyable,
Binary where Rs.length == 0,
)
A plain function called with its first two arguments swapped, returned by flip.
flip(f)(a, b, rest...) calls f(b, a, rest...); the remaining arguments
are borrowed. With no remaining parameters it is also a Binary.
Parameters
R(Movable & Deinitable): The function's result type.E(Movable & Deinitable): The function's error type,Neverfor a pure function.A0(Movable & Deinitable): The function's first parameter type.A1(Movable & Deinitable): The function's second parameter type.Rs(TypeList[...]): The types of the remaining parameters.
Implements
Binary, BinaryContract, Copyable
Fields
function(def(var a0: A0, var a1: A1, *args: *Rs) raises E thin -> R): The wrapped function.
Aliases
FirstSecondOutError
FlippedFunction.__call__ { #FlippedFunction.call .api-name }¶
def __call__(self, var first: A1, var second: A0, *rest: *Rs) raises E -> R
Call the function with its first two arguments swapped.
Arguments
first(var A1): Passed as the function's second argument.second(var A0): Passed as the function's first argument.*rest(*Rs): The remaining arguments, borrowed and passed in order.
Returns
R: The function's result.
Raises
E: The function's error, unchanged.
FlippedFunction.call¶
def call(self, var first: First, var second: Second) raises Error -> Out
Binary view: call the function with its two arguments swapped.
Arguments
first(var First): The first argument, passed second.second(var Second): The second argument, passed first.
Returns
Out: The function's result.
Raises
Error: The function's error, unchanged.
Identity¶
Source: fp/functions/composition.mojo
struct Identity[T](Unary, ImplicitlyCopyable)
The unary identity on T, returned by flow[T]() and compose[T]().
Parameters
T(Movable & Deinitable): The value type.
Implements
Copyable, ImplicitlyCopyable, Unary, UnaryContract
Aliases
ArgOutError: The error type;Neverfor a callable that does not raise.
Identity.__call__ { #Identity.call .api-name }¶
def __call__(self, var arg: T) -> T
Return the argument unchanged, as call does.
Arguments
arg(var T): The value, consumed.
Returns
T: arg itself.
Identity.call¶
def call(self, var arg: Arg) -> Out
Return the argument unchanged.
Arguments
arg(var Arg): The value, consumed.
Returns
Out: arg itself.
Partial¶
Source: fp/functions/partial.mojo
struct Partial[
R, E, Bs: TypeList[Trait=_Bound, ...], Rs: TypeList[Trait=_Rest, ...],
](
Copyable,
Thunk where Rs.length == 0,
Unary where Rs.length == 1,
Binary where Rs.length == 2,
)
A plain function with copies of its leading arguments, returned by partial.
Call it with the remaining arguments, which are borrowed. Each call passes
the function a fresh copy of every bound argument, so the stored values are
never consumed or changed. With 0, 1 or 2 remaining arguments it is also a
Thunk, Unary or Binary, which library higher-order functions accept.
Parameters
R(Movable & Deinitable): The function's result type.E(Movable & Deinitable): The function's error type,Neverfor a pure function.Bs(TypeList[...]): The bound argument types.Rs(TypeList[...]): The remaining parameter types.
Implements
Binary, BinaryContract, Copyable, Thunk, ThunkContract, Unary, UnaryContract
Fields
function(def(*args: *Rs) raises E thin -> R if (Int(len(values)) == Int(0)) else def(var a0: values[0], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(1)) else def(var a0: values[0], var a1: values[1], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(2)) else def(var a0: values[0], var a1: values[1], var a2: values[2], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(3)) else def(var a0: values[0], var a1: values[1], var a2: values[2], var a3: values[3], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(4)) else def(var a0: values[0], var a1: values[1], var a2: values[2], var a3: values[3], var a4: values[4], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(5)) else def(var a0: values[0], var a1: values[1], var a2: values[2], var a3: values[3], var a4: values[4], var a5: values[5], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(6)) else def(var a0: values[0], var a1: values[1], var a2: values[2], var a3: values[3], var a4: values[4], var a5: values[5], var a6: values[6], *args: *Rs) raises E thin -> R if (Int(len(values)) == Int(7)) else def(var a0: values[0], var a1: values[1], var a2: values[2], var a3: values[3], var a4: values[4], var a5: values[5], var a6: values[6], var a7: values[7], *args: *Rs) raises E thin -> R): The stored function.bound(Tuple[*values]): The bound arguments.
Aliases
ArgFirstSecondOutError
Partial.__call__ { #Partial.call .api-name }¶
def __call__(self, *rest: *Rs) raises E -> R
Call the function with the bound arguments followed by rest.
Arguments
*rest(*Rs): The remaining arguments, borrowed.
Returns
R: The function's result.
Raises
E: The function's error, unchanged.
Partial.call¶
def call(self, var arg: Arg) raises E -> R
Unary view: call the function when one argument remains.
Arguments
arg(var Arg): The remaining argument.
Returns
R: The function's result.
Raises
E: The function's error, unchanged.
2 more overloads
`Thunk` view: call the function when no arguments remain.
def call(self) raises E -> R
`Binary` view: call the function when two arguments remain.
def call(self, var first: First, var second: Second) raises E -> R
Piped¶
Source: fp/functions/pipeline.mojo
struct Piped[T](Movable)
A value in an eager chained pipeline, started by piped(value).
Each then applies one stage immediately, as pipe(value, f) does, and
infers that stage's types from its own call, so a chain has no stage limit
and takes plain functions, closures and library Unary values alike. get
ends the chain.
Parameters
T(Movable & Deinitable): The type of the value the chain holds.
Fields
value(T): The value the chain holds.
Piped.get¶
def get(deinit self) -> T
End the chain and return the value.
Returns
T: The value the chain holds, moved out.
Piped.then¶
def then[R, //, F: def(var T) -> R](deinit self, function: F) -> Piped[R]
Apply a pure stage and continue the chain with its result.
Parameters
R(Movable & Deinitable, inferred): The stage's result type.F(def(var T) -> R): The stage's type: a plain function or a closure.
Arguments
function(F): The stage, borrowed; it runs once, now.
Returns
Piped[R]: The chain, holding the stage's result.
def then[R, //, E: AnyType, F: def(var T) raises E -> R](
deinit self,
function: F,
) raises E -> Piped[R]
Apply a raising stage; its error stops the chain with its own type.
Limitations
Generic code that forwards a raising callback states its error,
then[E=X](f); Mojo 1.1 cannot infer it from a forwarded callback.
Parameters
R(Movable & Deinitable, inferred): The stage's result type.E(AnyType): The stage's error type.F(def(var T) raises E -> R): The stage's type: a plain function or a closure that raisesE.
Arguments
function(F): The stage, borrowed; it runs once, now.
Returns
Piped[R]: The chain, holding the stage's result.
Raises
E: The stage's error, unchanged; later stages do not run.
1 more overload
Apply a library `Unary` value, such as a partial or a composition.
def then[F: Unary](
deinit self,
function: F,
) raises F.Error -> Piped[F.Out] where F.Arg == T
Chain ten stages with piped¶
"""An order total in ten stages: plain functions, closures and partials, chained."""
from fp.functions import piped, partial
from std.testing import assert_equal
@fieldwise_init
struct PriceError(Movable, Writable):
var text: String
def parse_cents(text: String) raises PriceError -> Int:
try:
return atol(text)
except:
raise PriceError(text)
def multiply(factor: Int, cents: Int) -> Int: return factor * cents
def add(amount: Int, cents: Int) -> Int: return amount + cents
def not_negative(cents: Int) -> Int: return max(cents, 0)
def with_tax(cents: Int) -> Int: return cents + cents * 8 // 100
def to_nickel(cents: Int) -> Int: return (cents + 2) // 5 * 5
def dollars(cents: Int) -> String:
var rest = cents % 100
return "$" + String(cents // 100) + (".0" if rest < 10 else ".") + String(rest)
def label(amount: String) -> String: return "total: " + amount
def total(text: String, quantity: Int, percent: Int, shipping: Int) raises PriceError -> String:
def discount(cents: Int) {imm percent} -> Int:
return cents - cents * percent // 100
def ship(cents: Int) {imm shipping} -> Int:
return cents + shipping
return (piped(text)
.then(parse_cents)
.then(partial(multiply, quantity))
.then(discount)
.then(partial(add, -500))
.then(not_negative)
.then(ship)
.then(with_tax)
.then(to_nickel)
.then(dollars)
.then(label)
.get())
def main() raises:
var receipt = total("1999", 3, 10, 499)
assert_equal(receipt, "total: $58.30")
print(receipt)
try:
_ = total("19.99", 3, 10, 499)
except error:
print("invalid price:", error.text)
Run from the repository root pixi run mojo run -I src docs/examples/chained_pipeline.mojo
Output
total: $58.30
invalid price: 19.99
total("1999", 3, 10, 499) runs ten then stages: plain functions, two
closures that capture percent and shipping, and two partials. The price
1999 cents times 3 is 5997; the 10% discount gives 5398, the -500
coupon 4898, shipping 5397, and 8% tax 5828, which rounds to the nickel
as 5830 and prints as total: $58.30. With "19.99", parse_cents raises
PriceError, no later stage runs, and the program prints
invalid price: 19.99.
Bind leading arguments with partial¶
"""Bind leading arguments of a native function; bind keywords with a closure."""
from fp.functions import partial
def twice(var x: Int) -> Int:
return x * 2
def scale(factor: Int, x: Int) -> Int:
return factor * x
def main() raises:
var value = 4
var doubled = partial(twice, value)
print(doubled()) # 8
print(doubled()) # 8
var triple = partial(scale, 3)
print(triple(5)) # 15
# Keyword binding is a native closure with a capture list.
var base = 2
def basetwo(text: String) raises {base} -> Int:
return atol(text, base=base)
print(basetwo("10010")) # 18
Run from the repository root pixi run mojo run -I src docs/examples/partial.mojo
Output
8
8
15
18
partial(twice, value) copies 4 when it is built and passes a fresh copy on
each call, so doubled() returns 8 twice. partial(scale, 3) binds the first
argument, and triple(5) returns 15. partial binds only a positional
prefix, so the keyword base=2 is bound by the closure basetwo, which
returns 18 for "10010".