Skip to content
This repository was archived by the owner on May 23, 2024. It is now read-only.

Commit a21f75d

Browse files
committed
Merge pull request #136 from babbageclunk/23707
23707
2 parents 171afbd + 01bb4d5 commit a21f75d

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

src/23707.rs

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#![recursion_limit="2048"]
2+
3+
use std::marker::PhantomData;
4+
use std::fmt;
5+
use std::fmt::Debug;
6+
7+
pub struct Z( () );
8+
pub struct S<T> (PhantomData<T>);
9+
10+
11+
pub trait Nat {
12+
fn sing() -> Self;
13+
fn get(&self) -> usize;
14+
}
15+
16+
impl Nat for Z {
17+
fn sing() -> Z { Z( () ) }
18+
#[inline(always)]
19+
fn get(&self) -> usize {
20+
0
21+
}
22+
}
23+
24+
impl<T : Nat> Nat for S<T> {
25+
fn sing() -> S<T> { S::<T>( PhantomData::<T> ) }
26+
#[inline(always)]
27+
fn get(&self) -> usize {
28+
let prd : T = Nat::sing();
29+
1 + prd.get()
30+
}
31+
}
32+
33+
pub type N0 = Z;
34+
pub type N1 = S<N0>;
35+
pub type N2 = S<N1>;
36+
pub type N3 = S<N2>;
37+
pub type N4 = S<N3>;
38+
pub type N5 = S<N4>;
39+
40+
41+
pub struct Node<D : Nat>(usize,PhantomData<D>);
42+
43+
impl<D:Nat> Node<D> {
44+
pub fn push(&self, c : usize) -> Node<S<D>> {
45+
let Node(i,_) = *self;
46+
Node(10*i+c, PhantomData::<S<D>>)
47+
}
48+
}
49+
50+
impl<D:Nat> Node<S<D>> {
51+
pub fn pop(&self) -> (Node<D>,usize) {
52+
let Node(i,_) = *self;
53+
(Node(i/10, PhantomData::<D>), i-10*(i/10))
54+
}
55+
}
56+
57+
impl<D:Nat> Debug for Node<D> {
58+
fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
59+
let s : D = Nat::sing();
60+
write!(f, "Node<{}>: i= {}",
61+
s.get(), self.0)
62+
}
63+
}
64+
pub trait Step {
65+
fn step(&self, usize) -> Self;
66+
}
67+
68+
impl Step for Node<N0> {
69+
#[inline(always)]
70+
fn step(&self, n : usize) -> Node<N0> {
71+
println!("base case");
72+
Node(n,PhantomData::<N0>)
73+
}
74+
}
75+
76+
impl<D:Nat> Step for Node<S<D>>
77+
where Node<D> : Step {
78+
#[inline(always)]
79+
fn step(&self, n : usize) -> Node<S<D>> {
80+
println!("rec");
81+
let (par,c) = self.pop();
82+
let cnew = c+n;
83+
par.step(c).push(cnew)
84+
}
85+
86+
}
87+
88+
fn tst<D:Nat>(ref p : &Node<D>, c : usize) -> usize
89+
where Node<D> : Step {
90+
let Node(i,_) = p.step(c);
91+
i
92+
}
93+
94+
95+
96+
fn main() {
97+
let nd : Node<N3> = Node(555,PhantomData::<N3>);
98+
99+
// overflow...core::marker::Size
100+
let Node(g,_) = tst(nd,1);
101+
102+
// ok
103+
//let Node(g,_) = nd.step(1);
104+
105+
println!("{:?}", g);
106+
}

0 commit comments

Comments
 (0)