1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
crate::define! {
/// Identity function. Returns its input.
/// ```text
/// λx.x
/// ```
pub fn Identity ::= { Input. { Input }};
/// Takes two values and returns the first.
/// ```text
/// λa.λb.a
/// ```
pub fn FirstOf ::= { Input. { Constant<Input> }};
/// Returns its type parameter, ignoring input.
/// ```text
/// λv.I
/// ```
pub fn Constant<I> ::= { _Ignored. { I }};
/// Takes two values and returns the second.
/// ```text
/// λa.λb.b
/// ```
pub fn SecondOf ::= { _Ignored. { Identity }};
/// Composes a function with another.
/// Note that this returns a [`Composed`], for more ergonomic point-free form.
/// ```text
/// λf.λg.λx.fgx
/// ```
pub fn Compose ::= { A. B. { Composed<A, B> }};
/// The composition of two functions. See [`Compose`].
/// ```text
/// λx.FGx
/// ```
pub fn Composed<Fn, OtherFn>
::= { Input. { Fn, { OtherFn, Input }}}
where
OtherFn: Input,
Fn: {OtherFn, Input};
/// Takes a function and an input, and returns the function applied to said input.
/// ```text
/// λf.λx.fx
/// ```
pub fn Apply
::= { Fn. Input. { Fn, Input }}
where
Fn: Input;
/// S combinator. Takes three inputs, and applies the first to the second and third.
/// ```text
/// λx.λy.λz.xz(yz)
/// ```
pub fn Sheinfinkel ::= { X. Y. Z. {X, Z, { Y, Z }}} where
X: Z, Y: Z, {X, Z}: {Y, Z};
/// Takes a function that takes two arguments and the first argument to said function,
/// and returns a function that takes the second argument and runs the function with both.
/// See [`Curried`].
/// ```text
/// λf.λx.(λy.fxy)
/// ```
pub fn Curry
::= { Fn. Input. { Curried<Fn, Input>}};
/// Function that curries the first type argument with the second and the input. See [`Curry`].
/// ```text
/// λy.FXy
/// ```
pub fn Curried<Fn, X> ::= { Y. { Fn, X, Y }} where
Fn: X,
{Fn, X}: Y;
}