[−][src]Crate recur_fn
A library that provides a more flexible way to construct and extend the recursive function.
The RecurFn
trait is an abstraction of a recursive function.
By accepting a function parameter recur
as the recursion
rather than recurring directly, it makes constructing an
anonymous recursive function possible.
use recur_fn::{recur_fn, RecurFn}; let fib = recur_fn(|fib, n: i32| { if n <= 1 { n } else { fib(n - 1) + fib(n - 2) } }); assert_eq!(55, fib.call(10));
Beside, it makes extending the body of a recursive function possible.
use recur_fn::{recur_fn, RecurFn}; use std::cell::RefCell; let fib = recur_fn(|fib, n: i32| { if n <= 1 { n } else { fib(n - 1) + fib(n - 2) } }); let log = RefCell::new(Vec::new()); let fib_with_logging = recur_fn(|recur, n: i32| { log.borrow_mut().push(n); fib.body(recur, n) }); fib_with_logging.call(3); assert_eq!(*log.borrow(), vec![3, 2, 1, 0, 1]);
As recur_fn
is a convenient way to construct a RecurFn
,
calling it is slower than direct recursion.
To make it zero-cost, consider defining a struct,
implementing RecurFn
trait for it and mark the body
method by #[inline]
.
use recur_fn::RecurFn; let fib = { struct Fib {} impl RecurFn<i32, i32> for Fib { #[inline] fn body(&self, fib: impl Fn(i32) -> i32, n: i32) -> i32 { if n <= 1 { n } else { fib(n - 1) + fib(n - 2) } } } Fib {} }; assert_eq!(55, fib.call(10));
or if the function doesn't capture anything,
you can use recur_fn
macro.
use recur_fn::{recur_fn, RecurFn}; let fact = recur_fn!(fact(n: i32) -> i32 { if n == 0 { 1 } else { n * fact(n - 1) } }); assert_eq!(6, fact.call(3)); assert_eq!(0, fact.body(|_| 0, 3));
DynRecurFn
is a dynamic version of RecurFn
that allows you to have a trait object.
use recur_fn::{recur_fn, RecurFn, DynRecurFn}; use core::ops::Deref; let dyn_fact: &dyn DynRecurFn<_, _> = &recur_fn(|fact, n: i32| if n == 0 { 1 } else { n * fact(n - 1) });
Macros
recur_fn | Expands a function definition to defining a struct,
implementing |
Structs
Closure | A |
Direct | A |
FromPointer | A |
Traits
DynRecurFn | The dynamic version of |
RecurFn | The recursive function trait. |
Functions
direct | Constructs a non-recursive |
from_pointer | Returns a |
recur_fn | Constructs a |