[][src]Macro fix_fn::fix_fn

macro_rules! fix_fn {
    (
        $($mov:ident)? |$self_arg:ident $(, $arg_name:ident : $arg_type:ty)* $(,)? |
            -> $ret_type:ty
        $body:block
    ) => { ... };
    (
        $($mov:ident)? |$($arg_name:ident $(: $arg_type:ty)?),* $(,)?|
        $body:expr
    ) => { ... };
    (
        $($mov:ident)? |$self_arg:ident : $self_type:ty $(, $arg_name:ident $(: $arg_type:ty)?)* $(,)? |
            -> $ret_type:ty
        $body:block
    ) => { ... };
    (
        $($mov:ident)? |$self_arg:ident $(, $arg_name:ident $(: $arg_type:ty)?)* $(,)? |
            -> $ret_type:ty
        $body:block
    ) => { ... };
}

Takes a closure definition where the first parameter will be a Fn to the closure itself. Returns a recursive closure with the same signature, except the first parameter will be eliminated.

The passed closure needs to have at least one parameter. This first parameter can be used to call the closure itself, achieving recursion. It must not be annotated with a type.

Additional parameters will be parameters of the resulting closure. All additional parameters must be annotated with types.

The closure definition needs to have a result-type annotation.

move can be used and has the usual semantic.

Example

use fix_fn::fix_fn;
  
let fib = fix_fn!(|fib, i: u32| -> u32 {
    if i <= 1 {
        i
    } else {
        // fib will call the closure recursively
        fib(i - 1) + fib(i - 2)
    }
});

// resulting lambda only has the `i: u32` parameter
assert_eq!(fib(7), 13);