This question is about a limitation of Scala's implicit resolution system that I've run into a few times when using Scalaz and that doesn't make a lot of sense to me. I've distilled the problem to a Scalaz-less version below, but I'm happy to provide more information about motivation if needed.

Suppose I have a couple of type classes that witness something about a type constructor:

import scala.language.higherKinds

trait Foo[F[_]]
trait Bar[F[_], A]

Now also suppose that if I have a Foo instance for some F, I know I also have a Foo instance for Bar[F, _]:

implicit def barFoo[F[_]: Foo] = new Foo[({type L[X] = Bar[F, X]})#L] {}

I've also got instances for List and the right side of Either:

implicit object listFoo extends Foo[List]
implicit def eitherFoo[A] = new Foo[({type L[X] = Either[A, X]})#L] {}

Now it's pretty clear that I should be able to write the following:

type BarList[X] = Bar[List, X]

implicitly[Foo[BarList]]

Or, equivalently:

implicitly[Foo[({type L[X] = Bar[List, X]})#L]]

And indeed, both work exactly as expected.

So I try the following:

type StringOr[X] = Either[String, X]
type BarStringOr[X] = Bar[StringOr, X]

And then:

scala> implicitly[Foo[BarStringOr]]
res2: Foo[BarStringOr] = $anon$1@39a6c855

Again, no surprises here. But then I try:

implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]]

And I get the following:

<console>:15: error: could not find implicit value for parameter e: Foo[[X]Bar[[X]scala.util.Either[String,X],X]]
              implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]]
                        ^

Note that I have no problem i

Edit
Report