Compare commits

...

2 commits

7 changed files with 112 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "generic"
version = "0.1.0"

6
Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "generic"
version = "0.1.0"
edition = "2021"
[dependencies]

28
src/example.rs Normal file
View file

@ -0,0 +1,28 @@
use crate::generic::{Field, Sum, Generic};
struct IntPair {
a: i32,
b: i32
}
impl Generic for IntPair {
type Representation = Sum<Field<i32>, Field<i32>>;
fn generalize(self) -> Self::Representation {
Sum {
left: Field { value: self.a },
right: Field { value: self.b }
}
}
fn specialize(rep: Self::Representation) -> Self {
let Sum {
left: Field { value: a },
right: Field { value: b },
} = rep;
IntPair { a, b }
}
}
fn convert(x: IntPair) -> (i32, i32) {
Generic::specialize(x.generalize())
}

31
src/generic.rs Normal file
View file

@ -0,0 +1,31 @@
pub struct Sum<Con, Rhs> where Con: IsConType, Rhs: IsRepType {
pub left: Con,
pub right: Rhs,
}
pub struct Product<T, Rhs> where Rhs: IsConType {
pub left: Field<T>,
pub right: Rhs
}
pub struct Field<T> {
pub value: T
}
// types used for generic representation
pub trait IsRepType {}
impl<Lhs: IsConType, Rhs: IsRepType> IsRepType for Sum<Lhs, Rhs> {}
impl<T: IsRepType, Rhs: IsConType> IsRepType for Product<T, Rhs> {}
impl<T> IsRepType for Field<T> {}
// types that represent constructors
pub trait IsConType {}
impl<T, Rhs: IsConType> IsConType for Product<T, Rhs> {}
impl<T> IsConType for Field<T> {}
pub trait Generic {
type Representation: IsRepType;
fn generalize(self) -> Self::Representation;
fn specialize(rep: Self::Representation) -> Self;
}

21
src/instances.rs Normal file
View file

@ -0,0 +1,21 @@
use crate::generic::{Field, Generic, Sum};
impl<A, B> Generic for (A, B) {
type Representation = Sum<Field<A>, Field<B>>;
fn generalize(self) -> Self::Representation {
let (l, r) = self;
Sum {
left: Field { value: l },
right: Field { value: r }
}
}
fn specialize(rep: Self::Representation) -> Self {
let Sum {
left: Field { value: a },
right: Field { value: b },
} = rep;
(a, b)
}
}

18
src/lib.rs Normal file
View file

@ -0,0 +1,18 @@
pub mod generic;
mod example;
pub mod instances;
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}