Skip to content

Instantly share code, notes, and snippets.

@kyleheadley
Last active July 28, 2017 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyleheadley/5139d0056b102c0de944a54bf5688cda to your computer and use it in GitHub Desktop.
Save kyleheadley/5139d0056b102c0de944a54bf5688cda to your computer and use it in GitHub Desktop.
Show off type functions in rust with an example of 'type constructors'
// 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