#![crate_name="lambda"]
#![crate_type="lib"]
#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(non_ascii_idents)]
extern crate morphism;
#[allow(unused_imports)]
use morphism::{
Morphism
};
#[macro_export]
macro_rules! lambda {
( $closure:expr ) => { Morphism::new().tail($closure) }
}
#[macro_export]
macro_rules! λ {
( $($raw:tt)* ) => { lambda!( $($raw)* ) }
}
pub trait MorphismExt<'a, A, B> {
fn o<C, F: 'a>(self, f: F) -> Morphism<'a, A, C>
where
F: Fn(B) -> C;
}
impl<'a, A, B> MorphismExt<'a, A, B> for Morphism<'a, A, B> {
#[inline(always)]
fn o<C, F: 'a>(self, f : F) -> Morphism<'a, A, C>
where
F: Fn(B) -> C
{
self.tail(f)
}
}
#[cfg(test)]
mod tests {
use morphism::Morphism;
use super::MorphismExt;
#[test]
fn test_example_lambda_macro() {
assert_eq!(lambda!(| x | 42u * x).o(| x | (x, x))(1u), (42u, 42u));
}
#[test]
fn test_example_λ_macro() {
assert_eq!(λ!(| x | 42u * x).o(| x | (x, x))(1u), (42u, 42u));
}
#[test]
fn test_o() {
let f = λ!(| x | (0u + x,))
.o(| (x,) | (0u + x, 1u + x))
.o(| (x, y) | (0u + x, 1u + y, 2u + y))
.o(| (x, y, z) | (Some(z), Ok::<_, bool>(y), x.to_f64().unwrap() + 1.5f64));
assert_eq!(f(0), (Some(3), Ok(2), 1.5f64));
}
#[test]
fn test_example_readme() {
use std::iter::AdditiveIterator;
use std::num::Float;
let f =
λ!(| x | 2u64 * x)
.o(| x | 1.5f64 + x.to_f64().unwrap())
.o(| x | x.floor().to_u64().unwrap());
let res = range(0u64, 9).map(f).sum();
assert_eq!(res, 81);
}
}