69 lines
1.5 KiB
Rust
69 lines
1.5 KiB
Rust
use std::ops::Add;
|
|
|
|
pub enum Sum<Con, Rhs> where Con: IsConType, Rhs: IsRepType {
|
|
Left(Con),
|
|
Right(Rhs),
|
|
}
|
|
|
|
pub struct Product<T, Rhs> where Rhs: IsConType {
|
|
pub left: T,
|
|
pub right: Rhs
|
|
}
|
|
|
|
impl<Field, Rest, RestRhs, FieldRhs> Add<Product<FieldRhs, RestRhs>> for Product<Field, Rest>
|
|
where
|
|
Rest: Add<RestRhs> + IsConType,
|
|
Field: Add<FieldRhs>,
|
|
RestRhs: IsConType,
|
|
Rest::Output: IsConType
|
|
{
|
|
type Output = Product<Field::Output, Rest::Output>;
|
|
|
|
fn add(self, other: Product<FieldRhs, RestRhs>) -> Self::Output {
|
|
Product {
|
|
left: self.left + other.left,
|
|
right: self.right + other.right
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
pub struct Field<T> {
|
|
pub value: T
|
|
}
|
|
|
|
impl<R, T: Add<R>> Add<Field<R>> for Field<T> {
|
|
type Output=Field<T::Output>;
|
|
|
|
fn add(self, rhs: Field<R>) -> Self::Output {
|
|
Field {
|
|
value: self.value + rhs.value,
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// types used for generic representation
|
|
pub trait IsRepType {}
|
|
|
|
impl<Lhs, Rhs> IsRepType for Sum<Lhs, Rhs>
|
|
where Lhs: IsConType, Rhs: IsRepType {}
|
|
|
|
impl<T, Rhs> IsRepType for Product<T, Rhs>
|
|
where Rhs: IsConType {}
|
|
|
|
impl<T> IsRepType for Field<T> {}
|
|
|
|
// types that represent constructors
|
|
pub trait IsConType {}
|
|
impl<T, Rhs> IsConType for Product<T, Rhs>
|
|
where Rhs: IsConType {}
|
|
impl<T> IsConType for Field<T> {}
|
|
|
|
|
|
pub trait Generic {
|
|
type Representation: IsRepType;
|
|
fn generalize(self) -> Self::Representation;
|
|
fn specialize(rep: Self::Representation) -> Self;
|
|
}
|
|
|