尝试编写类似于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();
}
答案 0 :(得分:3)
有人可能会将Peano
特征推向另一种类型,即使是在另一个类型中,然后主要的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);
...但是,它看起来不太好。