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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! List encoding conversions

#![allow(missing_docs)]

use term::{Term, abs, app};
use term::Term::*;
use data::num::convert::*;

macro_rules! make_trait {
    ($trait_name:ident, $function_name:ident) => (
        pub trait $trait_name {
            #[doc="Performs the conversion."]
            fn $function_name(self) -> Term;
        }
    );
}

make_trait!(IntoPairList, into_pair_list);
make_trait!(IntoChurchList, into_church);
make_trait!(IntoScottList, into_scott);
make_trait!(IntoParigotList, into_parigot);

impl IntoPairList for Vec<Term> {
    fn into_pair_list(self) -> Term {
        let mut ret = abs!(2, Var(1));

        for t in self.into_iter().rev() {
            ret = abs(app!(Var(1), t, ret))
        }

        ret
    }
}

impl IntoChurchList for Vec<Term> {
    fn into_church(self) -> Term {
        let mut ret = Var(2);

        for t in self.into_iter().rev() {
            ret = app!(Var(1), t, ret);
        }

        abs!(2, ret)
    }
}

impl<T: IntoChurchNum> IntoChurchList for Vec<T> {
    fn into_church(self) -> Term {
        self.into_iter().map(|t| t.into_church()).collect::<Vec<Term>>().into_church()
    }
}

impl IntoScottList for Vec<Term> {
    fn into_scott(self) -> Term {
        let mut ret = abs!(2, Var(2));

        for t in self.into_iter().rev() {
            ret = abs!(2, app!(Var(1), t, ret));
        }

        ret
    }
}

impl<T: IntoScottNum> IntoScottList for Vec<T> {
    fn into_scott(self) -> Term {
        self.into_iter().map(|t| t.into_scott()).collect::<Vec<Term>>().into_scott()
    }
}

impl IntoParigotList for Vec<Term> {
    fn into_parigot(self) -> Term {
        let mut ret  = abs!(2, Var(2));

        for t in self.into_iter().rev() {
            ret = abs!(2, app!(Var(1), t, ret.clone(), ret.unabs().and_then(|r| r.unabs()).unwrap()));
        }

        ret
    }
}

impl<T: IntoParigotNum> IntoParigotList for Vec<T> {
    fn into_parigot(self) -> Term {
        self.into_iter().map(|t| t.into_parigot()).collect::<Vec<Term>>().into_parigot()
    }
}