Last active
July 28, 2017 21:46
-
-
Save kyleheadley/5139d0056b102c0de944a54bf5688cda to your computer and use it in GitHub Desktop.
Show off type functions in rust with an example of 'type constructors'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// emulates the type of a function from types 'E' to sequence-like types | |
pub trait SeqTypeFn<E> { type Result : SeqLike<E>; } | |
// sequence-like interface | |
pub trait SeqLike<E>{ | |
fn new() -> Self; | |
fn push(self,e:E) -> Self; | |
fn first(&self) -> Option<&E>; | |
} | |
// List type - pushes to front | |
pub struct ListConstructor; | |
pub enum List<E>{ | |
Nil, Cons(E,Box<List<E>>) | |
} | |
impl<E> SeqTypeFn<E> for ListConstructor { | |
type Result = List<E>; | |
} | |
impl<E> SeqLike<E> for List<E> { | |
fn new() -> Self { List::Nil } | |
fn push(self,e:E) -> Self { List::Cons(e,Box::new(self)) } | |
fn first(&self) -> Option<&E> { | |
match *self{ | |
List::Nil => None, | |
List::Cons(ref e,_) => Some(e), | |
} | |
} | |
} | |
// Vect type - pushes to end | |
pub struct VectConstructor; | |
pub struct Vect<E>(Vec<E>); | |
impl<E> SeqTypeFn<E> for VectConstructor { | |
type Result = Vect<E>; | |
} | |
impl<E> SeqLike<E> for Vect<E> { | |
fn new() -> Self { Vect(Vec::new()) } | |
fn push(self,e:E) -> Self { | |
let mut v = self.0; | |
v.push(e); | |
Vect(v) | |
} | |
fn first(&self) -> Option<&E> { self.0.first() } | |
} | |
fn main() { | |
// four similar code blocks | |
// list usize | |
type T1 = <ListConstructor as SeqTypeFn<usize>>::Result; | |
let a = T1::new(); | |
let a = a.push(1).push(2); | |
let a = a.first(); | |
println!("list first usize: {:?}",a); | |
// vect usize | |
type T2 = <VectConstructor as SeqTypeFn<usize>>::Result; | |
let a = T2::new(); | |
let a = a.push(1).push(2); | |
let a = a.first(); | |
println!("vect first usize: {:?}",a); | |
// list char | |
type T3 = <ListConstructor as SeqTypeFn<char>>::Result; | |
let a = T3::new(); | |
let a = a.push('1').push('2'); | |
let a = a.first(); | |
println!("list first char: {:?}",a); | |
// vect char | |
type T4 = <VectConstructor as SeqTypeFn<char>>::Result; | |
let a = T4::new(); | |
let a = a.push('1').push('2'); | |
let a = a.first(); | |
println!("vect first char: {:?}",a); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment