Expand description
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§
- Expands a function definition to defining a struct, implementing
RecurFn
for the struct and constructing it. It can be useful if you want a zero-costRecurFn
implementation.
Structs§
- A
RecurFn
that uses a closure as the body. - A
RecurFn
that doesn’t callrecur
parameter in its body. - A
RecurFn
that delegates to a pointer to aRecurFn
.
Traits§
- The dynamic version of
RecurFn
that supports trait object. - The recursive function trait.
Functions§
- Constructs a non-recursive
RecurFn
callingf
directly. - Returns a
RecurFn
implementation from a pointer toRecurFn
, i.e. a implementation ofDeref
whoseTarget
implementsRecurFn
. - Constructs a
RecurFn
with the body speicified.