类型级别的斐波那契序列导致“评估需求的溢出”

时间:2018-12-09 05:12:05

标签: rust type-level-computation

我正在写一个类型级别的斐波那契序列。我已经写了一个类型级别的附加功能,效果很好。每个数字都表示为Inc<Inc<...<Zero>...>>。有一个特征Add,然后结构Bop<Left, Right>(二进制操作)实现了Add特征。用法是<Bop<Inc<Inc<Inc<Zero>>>, Inc<Inc<Zero>>> as Add>::Get将是Inc<Inc<Inc<Inc<Inc<Zero>>>>>,即3 + 2 = 5。

然后我根据加法写一个斐波那契数列:

use std::marker::PhantomData;
struct Zero {}
struct Inc<T> {
    _phantom: PhantomData<T>,
}

struct Bop<Left, Right> {
    _phantom_l: PhantomData<Left>,
    _phantom_r: PhantomData<Right>,
}

trait Add {
    type Get;
}

impl<Left> Add for Bop<Left, Zero> {
    type Get = Left;
}

impl<Left, RightInner> Add for Bop<Left, Inc<RightInner>>
where
    Bop<Left, RightInner>: Add,
{
    type Get = Inc<<Bop<Left, RightInner> as Add>::Get>;
}

type One = Inc<Zero>;
type Two = Inc<One>;
type Three = Inc<Two>;
type Four = Inc<Three>;
type Five = Inc<Four>;
// then <Bop<Three, Two> as Add>::Get will be type Five

// 0 1 2 3 4 5 6 7
// 0 1 1 2 3 5 8 13
// usage: <Inc<Inc<Inc<Zero>>> as Fib>::Get should be the third fib number,
// i.e. 2, or Inc<Inc<Zero>>
trait Fib {
    type Get;
}
impl Fib for Zero {
    type Get = Zero;
}
impl Fib for One {
    type Get = One;
}

impl<T> Fib for Inc<Inc<T>>
where
    T: Fib,
    Inc<T>: Fib,
    Bop<<T as Fib>::Get, <Inc<T> as Fib>::Get>: Add,
{
    type Get = <Bop<<T as Fib>::Get, <Inc<T> as Fib>::Get> as Add>::Get;
}

fn main() {}

complete example

编译器在弄清楚impl<T> Fib for Uop<Inc<Inc<T>>>部分时遇到麻烦,它抱怨:

error[E0275]: overflow evaluating the requirement `Inc<_>: Fib`
  |
  = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<_>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<_>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<_>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<_>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>>>>>>`
  = note: required because of the requirements on the impl of `Fib` for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<_>>>>>>>>>>>>>>`

// cut off more

错误原因是什么?如何解决?

0 个答案:

没有答案