В следующем упрощенном примере кода:
case class One[A](a: A) // An identity functor
case class Twice[F[_], A](a: F[A], b: F[A]) // A functor transformer
type Twice1[F[_]] = ({type L[α] = Twice[F, α]}) // We'll use Twice1[F]#L when we'd like to write Twice[F]
trait Applicative[F[_]] // Members omitted
val applicativeOne: Applicative[One] = null // Implementation omitted
def applicativeTwice[F[_]](implicit inner: Applicative[F]): Applicative[({type L[α] = Twice[F, α]})#L] = null
Я могу вызвать applativeTwice on applativeOne и работать с выводами типа, как только я попытаюсь называть его applyativeTwice (applyativeOne), вывод не выполняется:
val aOK = applicativeTwice(applicativeOne)
val bOK = applicativeTwice[Twice1[One]#L](applicativeTwice(applicativeOne))
val cFAILS = applicativeTwice(applicativeTwice(applicativeOne))
Ошибки в scala 2.10.0:
- type mismatch;
found : tools.Two.Applicative[[α]tools.Two.Twice[tools.Two.One,α]]
required: tools.Two.Applicative[F]
- no type parameters for method applicativeTwice:
(implicit inner: tools.Two.Applicative[F])tools.Two.Applicative[[α]tools.Two.Twice[F,α]]
exist so that it can be applied to arguments
(tools.Two.Applicative[[α]tools.Two.Twice[tools.Two.One,α]])
--- because ---
argument expression type is not compatible with formal parameter type;
found : tools.Two.Applicative[[α]tools.Two.Twice[tools.Two.One,α]]
required: tools.Two.Applicative[?F]
Почему бы "? F" не совпасть ни с чем (с правильным видом)? В конечном счете, я бы хотел, чтобы applativeTwice был неявной функцией, но сначала мне нужно было бы получить вывод типа. Я видел подобные вопросы, и ответы указывали на ограничения в алгоритмах вывода типов. Но этот случай кажется довольно ограниченным и должен быть довольно раздражающим в монадных трансформаторах, поэтому я подозреваю, что мне не хватает трюка, чтобы обойти это.