scala – 类型别名和类型羊羔之间的区别
这个问题是关于
Scala隐式解析系统的一个局限性,我在使用Scalaz时遇到了几次,这对我来说并没有什么意义.我已经将问题解决了下面的无Scalaz的版本,但是如果需要,我很乐意提供有关动机的更多信息.
假设我有几个类型的类可以看到有关类型构造函数的东西: import scala.language.higherKinds trait Foo[F[_]] trait Bar[F[_],A] 现在也假设如果我有一个F的F实例,我知道我也有一个Foo实例的酒吧[F,_]: implicit def barFoo[F[_]: Foo] = new Foo[({type L[X] = Bar[F,X]})#L] {} 我还有List的实例和右边的任一个: 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] = $anon$1@39a6c855 再次,这里没有惊喜.但是我尝试: 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]] ^ 请注意,我没有问题推断出StringOr的必要Foo实例,或者显式调用barFoo来获取所需的实例: scala> implicitly[Foo[StringOr]] res4: Foo[StringOr] = $anon$1@3eaac006 scala> barFoo[StringOr] res5: Foo[[X]Bar[StringOr,X]] = $anon$1@179fbfea 我无法确定List和StringOr之间可能存在什么重要区别,允许lambda类型适用于前者,而不是后者. 我已经在Scala 2.10.0-RC5和2.9.2上试过了.增加协方差整体没有帮助. 我错过了什么吗?有人可以指出我在规范中的某些东西,这将有助于我理解这一点,还是以前讨论过类似的问题? 解决方法
好的,我不是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) 这个问题是Scala的无能为力推断出barFoo的类型参数为[X] [java.lang.String,X].这似乎是由于(或至少与scalac’s refusal to infer a partially applied type constructor相关). (在相关的说明中,这是Scala认为不可接受的复杂类型之一的例子). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |