Rust 不会缩小类型范围吗?或者我犯了一个错误

标签 rust rust-obsolete

尝试编写类似于 Haskell 的 HList 的东西,具有按类型搜索的功能。使用以下代码,在 play.rust-lang.org 版本 rustc 0.13.0-dev (567b90ff0 2014-12-13 20:02:15 +0000) 中,我收到错误:

<anon>:35:26: 35:31 error: unable to infer enough type information to locate the impl of the trait `ContainsRel<int, _>` for the type `HCons<int, HNil>`; type annotations required
<anon>:35     let foo: &int = list.get();
                                   ^~~~~

我不确定为什么它无法推断出正确的类型,HNil 没有 ContainsRel impls。

trait HList {}

struct HNil;
struct HCons<H, T: HList>(H, T);

impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}


trait Peano {}

struct Zero;
struct Succ<N: Peano>(N);

impl Peano for Zero {}
impl<N: Peano> Peano for Succ<N> {}

trait ContainsRel<E, P: Peano> {
    fn get(&self) -> &E;
}

impl<E, L: HList> ContainsRel<E, Zero> for HCons<E, L> {
    fn get(&self) -> &E {
        &self.0
    }
}
impl<E, X, L: ContainsRel<E, P>+HList, P: Peano> ContainsRel<E, Succ<P>> for HCons<X, L> {
    fn get(&self) -> &E {
        self.1.get()
    }
}

fn main() {
    let list: HCons<uint, HCons<int, HNil>> = HCons(5u, HCons(6i, HNil));
    let foo: &int = list.get();
}

最佳答案

有人可以为另一种类型实现 Peano 特征,即使是在另一个箱子中,然后 main 中的 list.get() 就会变得不明确。 如果您尝试在 impl 中手动替换类型,您将得到:

impl <E=int, X=uint , L=HCons<int, HNil>, P=?> ContainsRel<int, Succ<P=?>> for HCons<uint, HCons<int,HNil>>

对于到目前为止定义的类型,P 必须为零(因为它是范围内 Peano 的唯一实现),但任何人都可以定义另一个结构体在另一个模块中实现 P,所以 Rust 迫使你必须明确。 例如,添加以下内容是有效的:

struct Foo;
impl Peano for Foo {}
impl<E, L: HList> ContainsRel<E, Foo> for HCons<E, L> {
    fn get(&self) -> &E {
        &self.0
    }
}

指定P作品的类型:

let foo: &int = ContainsRel::<_, Succ<Zero>>::get(&list);

...但是,是的,它看起来不太好。

关于Rust 不会缩小类型范围吗?或者我犯了一个错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27477482/

相关文章:

rust - 结构必须长于成员引用

c - 将 C 数组传递给 Rust 函数

rust - Rust指针与向量的解除引用

rust - &T 和 T/&, ~T 和 T/~ 的区别

rust - 比较字符串和静态字符串

rust - 如何用其他常量初始化顶级常量?

rust diesel-cli 为不同的环境设置多个 env 文件

data-structures - "overflow while adding drop-check rules"实现手指树时

rust - Rust 0.10 中的条件编译?