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
#[derive (Debug, PartialEq, Eq)] pub enum Fix<A> { Pro(A), Fix(A) } impl<A> Fix<A> { pub fn map<B, F: FnOnce(A) -> B>(self, f: F) -> Fix<B> { match self { Fix::Pro(a) => Fix::Pro(f(a)), Fix::Fix(a) => Fix::Fix(f(a)) } } } pub fn compose<A, F, G>(a: A, mut f: F, mut g: G) -> Fix<A> where F: FnMut(A) -> Fix<A>, G: FnMut(A) -> Fix<A> { match f(a) { Fix::Fix(b) => g(b), fix => fix } } pub fn fix<A, F: FnMut(A) -> Fix<A>>(mut a: A, mut f: F) -> A { loop { match f(a) { Fix::Fix(b) => return b, Fix::Pro(b) => a = b } } } pub fn fix_result<A, E, F: FnMut(A) -> Result<Fix<A>, E>>(mut a: A, mut f: F) -> Result<A, E> { loop { match f(a) { Result::Err(err) => return Result::Err(err), Result::Ok(Fix::Fix(b)) => return Result::Ok(b), Result::Ok(Fix::Pro(b)) => a = b } } }