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
use std::marker::PhantomData;
pub trait SealedNat {}
pub trait Nat: SealedNat + Send + Copy + 'static
{
#[allow(non_upper_case_globals)]
const Value: Self;
fn nat() -> Self;
}
#[derive(Copy, Clone)]
pub struct Z;
#[derive(Copy, Clone)]
pub struct S<N>(pub PhantomData<N>);
impl SealedNat for Z {}
impl Nat for Z
{
#[allow(non_upper_case_globals)]
const Value: Z = Z;
fn nat() -> Z
{
Z
}
}
impl<N> SealedNat for S<N> where N: Nat {}
impl<N> Nat for S<N>
where
N: Nat,
{
#[allow(non_upper_case_globals)]
const Value: S<N> = S(PhantomData);
fn nat() -> S<N>
{
S(PhantomData)
}
}
pub fn succ<N>(_: N) -> S<N>
{
S(PhantomData)
}