2012-12-21 136 views
12

这个问题是关于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] {} 

我也得到了实例的ListEither右侧:

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。添加协方差无助于事。

我错过了一些明显的东西吗?有人能够指出我在规范中的某些内容,这些内容可以帮助我理解这一点,或者以前对类似问题的讨论?

+0

我不确定这个话题,但它似乎与https://issues.scala-lang.org/browse/SI-2712 – aemxdp

+0

@andriyp:谢谢,但我不是当然,我明白这是如何相关的。 –

+0

特拉维斯还在https://issues.scala-lang.org/browse/SI-6895上打开了一张票 –

回答

4

好吧,我不是100%确定的,但我认为我们可以通过将此减少到最简单的情况下取得一些进展。含义不是这里的问题,也不是类型别名。这足以失败:

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

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

val res1: Foo[({type L[X] = Either[String, X]})#L] = null 

val works = barFoo[({type L[X] = Either[String, X]})#L](res1) 
val fails = barFoo(res1) 

问题issems是Scala的inabality推断为barFoo[X]Either[java.lang.String,X]类型参数。这似乎是由于(或至少与scalac's refusal to infer a partially applied type constructor有关)。

(在相关说明中,这是斯卡拉认为难以接受的复杂类型之一的例子)。

相关问题