I'm attempting to adapt the higher kinded types trick in the linked blog post to my scenario. Essentially, I have a trait with a method that needs to vary the return value based on the implementing concrete type.
I'm able to recreate the code samples in the link on the playground and they work as intended. However, when I modify the example to this minimal repro:
struct Foo<T> {
_phantom: std::marker::PhantomData<T>
}
trait Hkt<B> {
type R;
}
impl<A, B> Hkt<B> for Foo<A> {
type R = u64;
}
trait Horse {
fn horse<B>(&self) -> <Self as Hkt<B>>::R where Self: Hkt<B>;
}
impl<A> Horse for Foo<A> {
fn horse<B>(&self) -> <Self as Hkt<B>>::R where Self: Hkt<B> {
16u64
}
}
I get the error:
error[E0308]: mismatched types
--> src/lib.rs:20:9
|
18 | fn horse<B>(&self) -> <Self as Hkt<B>>::R where Self: Hkt<B> {
| ------------------- expected `<Foo<A> as Hkt<B>>::R` because of return type
20 | 16u64
| ^^^^^ expected associated type, found `u64`
|
= note: expected associated type `<Foo<A> as Hkt<B>>::R`
found type `u64`
= help: consider constraining the associated type `<Foo<A> as Hkt<B>>::R` to `u64` or calling a method that returns `<Foo<A> as Hkt<B>>::R`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (lib) due to 1 previous error
I'm failing to see what I'm doing wrong. For all B, A
, all Foo<A>
impls Hkt<B>
, so horse()
should resolve to a u64
. What gives?