这个问题是关于Scala的隐式解析系统的限制,我在使用Scalaz时遇到过几次,这对我没有多大意义。我已经将这个问题提炼成了一个无Scalaz的版本,但是我很乐意提供更多关于激励的信息,如果需要的话。类型别名和类型lambda之间的区别
假设我有一对夫妇类型的类中的证人有一个什么类型的构造函数:
import scala.language.higherKinds
trait Foo[F[_]]
trait Bar[F[_], A]
现在也想,如果我有一些F
一个Foo
例如,我知道我也有一个Foo
实例Bar[F, _]
:
implicit def barFoo[F[_]: Foo] = new Foo[({type L[X] = Bar[F, X]})#L] {}
我也得到了实例的List
和Either
右侧:
implicit object listFoo extends Foo[List]
implicit def eitherFoo[A] = new Foo[({type L[X] = Either[A, X]})#L] {}
现在,很明显,我应该能够编写如下:
type BarList[X] = Bar[List, X]
implicitly[Foo[BarList]]
,或等效:
implicitly[Foo[({type L[X] = Bar[List, X]})#L]]
事实上,无论是工作完全按预期。
所以我尝试以下方法:
type StringOr[X] = Either[String, X]
type BarStringOr[X] = Bar[StringOr, X]
然后:
scala> implicitly[Foo[BarStringOr]]
res2: Foo[BarStringOr] = [email protected]
同样,这里没有惊喜。但后来我尝试:
implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]]
而且我得到以下几点:
<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]]
^
请注意,我没有问题,推断出必要的Foo
实例StringOr
,或致电barFoo
明确地获得所需的实例:
scala> implicitly[Foo[StringOr]]
res4: Foo[StringOr] = [email protected]
scala> barFoo[StringOr]
res5: Foo[[X]Bar[StringOr,X]] = [email protected]
我无法识别之间可能存在的重要区别和StringOr
个案,它们允许类型lambda版本适用于前者,但不适用于后者。
我试过这个Scala 2.10.0-RC5和2.9.2。添加协方差无助于事。
我错过了一些明显的东西吗?有人能够指出我在规范中的某些内容,这些内容可以帮助我理解这一点,或者以前对类似问题的讨论?
我不确定这个话题,但它似乎与https://issues.scala-lang.org/browse/SI-2712 – aemxdp
@andriyp:谢谢,但我不是当然,我明白这是如何相关的。 –
特拉维斯还在https://issues.scala-lang.org/browse/SI-6895上打开了一张票 –