From 1a43c2d1a5c76fa05c163c0c7bfceb8523e74e06 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 2 May 2025 19:38:30 +0200 Subject: [PATCH] trait definition and struct-tuple example --- .gitignore | 1 + Cargo.lock | 7 +++++++ Cargo.toml | 6 ++++++ src/example.rs | 28 ++++++++++++++++++++++++++++ src/generic.rs | 31 +++++++++++++++++++++++++++++++ src/instances.rs | 21 +++++++++++++++++++++ src/lib.rs | 18 ++++++++++++++++++ 7 files changed, 112 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/example.rs create mode 100644 src/generic.rs create mode 100644 src/instances.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b69769b --- /dev/null +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c1c4ae5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "generic" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/example.rs b/src/example.rs new file mode 100644 index 0000000..8b92e11 --- /dev/null +++ b/src/example.rs @@ -0,0 +1,28 @@ +use crate::generic::{Field, Sum, Generic}; + + +struct IntPair { + a: i32, + b: i32 +} + +impl Generic for IntPair { + type Representation = Sum, Field>; + 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()) +} diff --git a/src/generic.rs b/src/generic.rs new file mode 100644 index 0000000..c12c299 --- /dev/null +++ b/src/generic.rs @@ -0,0 +1,31 @@ +pub struct Sum where Con: IsConType, Rhs: IsRepType { + pub left: Con, + pub right: Rhs, +} + +pub struct Product where Rhs: IsConType { + pub left: Field, + pub right: Rhs +} + +pub struct Field { + pub value: T +} + +// types used for generic representation +pub trait IsRepType {} +impl IsRepType for Sum {} +impl IsRepType for Product {} +impl IsRepType for Field {} + +// types that represent constructors +pub trait IsConType {} +impl IsConType for Product {} +impl IsConType for Field {} + + +pub trait Generic { + type Representation: IsRepType; + fn generalize(self) -> Self::Representation; + fn specialize(rep: Self::Representation) -> Self; +} diff --git a/src/instances.rs b/src/instances.rs new file mode 100644 index 0000000..f470fd1 --- /dev/null +++ b/src/instances.rs @@ -0,0 +1,21 @@ +use crate::generic::{Field, Generic, Sum}; + +impl Generic for (A, B) { + type Representation = Sum, Field>; + + 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) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..dc859d7 --- /dev/null +++ b/src/lib.rs @@ -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); + } +}