Compare commits
2 commits
76eb80517f
...
5af0d4eb2d
Author | SHA1 | Date | |
---|---|---|---|
5af0d4eb2d | |||
1a43c2d1a5 |
7 changed files with 112 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal 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
6
Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "generic"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
28
src/example.rs
Normal file
28
src/example.rs
Normal 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
31
src/generic.rs
Normal 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
21
src/instances.rs
Normal 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
18
src/lib.rs
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue