trait definition and struct-tuple example
This commit is contained in:
commit
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