Próbuję wprowadzić mnożenie na poziomie typu w Rust.Mnożenie poziomu rdzy
Dodawanie już działa, ale mam problemy z "tymczasową" zmienną typu.
Kod:
use std::marker::PhantomData;
//Trait for the type level naturals
trait Nat {}
impl Nat for Zero {}
impl<T: Nat> Nat for Succ<T> {}
//Zero and successor types
struct Zero;
struct Succ<T: Nat>(PhantomData<T>);
//Type level addition
trait Add<B,C>
where Self: Nat,
B: Nat,
C: Nat
{}
impl<B: Nat> Add<B,B> for Zero {}
impl<A: Nat,B: Nat,C: Nat> Add<B,C> for Succ<A>
where A: Add<Succ<B>,C>
{}
fn add<A: Nat, B: Nat, C: Nat>(
a: PhantomData<A>,
b: PhantomData<B>)
-> PhantomData<C>
where A: Add<B,C> { PhantomData }
//Type level multiplication
trait Mult<B,C>
where Self: Nat,
B: Nat,
C: Nat,
{}
impl<B: Nat> Mult<B,Zero> for Zero {}
//ERROR HERE: "unconstrained type parameter 'C'"
//impl<A: Nat, B: Nat,C: Nat, D: Nat> Mult<B,D> for Succ<A>
// where A: Mult<B,C>,
// B: Add<C,D>
// {}
fn main() {
let x: PhantomData<Succ<Succ<Zero>>> = PhantomData;
let y: PhantomData<Succ<Zero>> = PhantomData;
//uncomment ': i32' in the next line to see infered type
let z /*: i32*/ = add(x,y);
}
Oddelegowany kompiluje kod działa dobrze i dodawania. Gdybym odkomentuj ERROR TUTAJ sekcję otrzymuję następujący komunikat o błędzie:
error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:40:21
|
40 | impl<A: Nat, B: Nat,C: Nat, D: Nat> Mult<B,D> for Succ<A>
| ^unconstrained type parameter
error: aborting due to previous error
error: Could not compile `4_18_generics`.
To learn more, run the command again with --verbose.
Czy istnieje sposób, aby wykorzystać takie „tymczasowe pośredniej /” Parametry typu?
Czy mnożenie jest możliwe w jakikolwiek inny sposób (obecnie nie myślę o)?
Czy generalnie nie jest to możliwe?
Czy będzie to możliwe w przyszłej wersji językowej?
Próbowałem zrobić to jak w Haskell (tak czy inaczej ...). Wiem, że nie zabieram tego rodzaju rzeczy za burtę. :-) Dziękuję za doskonałą odpowiedź! – Lazarus535
@ Lazarus535: Ale ... Ale ... Za burtą jest zabawa! : D –
Zdecydowanie jest! Naprawdę przepisuję teraz mały projekt w Rust, ale zawsze rozpraszam się takimi rzeczami. :-RE – Lazarus535