這個問題是關於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上打開了一張票 –