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

23707 #136

Merged
merged 1 commit into from
Nov 6, 2015
Merged

23707 #136

Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions src/23707.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#![recursion_limit="2048"]

use std::marker::PhantomData;
use std::fmt;
use std::fmt::Debug;

pub struct Z( () );
pub struct S<T> (PhantomData<T>);


pub trait Nat {
fn sing() -> Self;
fn get(&self) -> usize;
}

impl Nat for Z {
fn sing() -> Z { Z( () ) }
#[inline(always)]
fn get(&self) -> usize {
0
}
}

impl<T : Nat> Nat for S<T> {
fn sing() -> S<T> { S::<T>( PhantomData::<T> ) }
#[inline(always)]
fn get(&self) -> usize {
let prd : T = Nat::sing();
1 + prd.get()
}
}

pub type N0 = Z;
pub type N1 = S<N0>;
pub type N2 = S<N1>;
pub type N3 = S<N2>;
pub type N4 = S<N3>;
pub type N5 = S<N4>;


pub struct Node<D : Nat>(usize,PhantomData<D>);

impl<D:Nat> Node<D> {
pub fn push(&self, c : usize) -> Node<S<D>> {
let Node(i,_) = *self;
Node(10*i+c, PhantomData::<S<D>>)
}
}

impl<D:Nat> Node<S<D>> {
pub fn pop(&self) -> (Node<D>,usize) {
let Node(i,_) = *self;
(Node(i/10, PhantomData::<D>), i-10*(i/10))
}
}

impl<D:Nat> Debug for Node<D> {
fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
let s : D = Nat::sing();
write!(f, "Node<{}>: i= {}",
s.get(), self.0)
}
}
pub trait Step {
fn step(&self, usize) -> Self;
}

impl Step for Node<N0> {
#[inline(always)]
fn step(&self, n : usize) -> Node<N0> {
println!("base case");
Node(n,PhantomData::<N0>)
}
}

impl<D:Nat> Step for Node<S<D>>
where Node<D> : Step {
#[inline(always)]
fn step(&self, n : usize) -> Node<S<D>> {
println!("rec");
let (par,c) = self.pop();
let cnew = c+n;
par.step(c).push(cnew)
}

}

fn tst<D:Nat>(ref p : &Node<D>, c : usize) -> usize
where Node<D> : Step {
let Node(i,_) = p.step(c);
i
}



fn main() {
let nd : Node<N3> = Node(555,PhantomData::<N3>);

// overflow...core::marker::Size
let Node(g,_) = tst(nd,1);

// ok
//let Node(g,_) = nd.step(1);

println!("{:?}", g);
}