2012-12-21 132 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有關)。

(在相關說明中,這是斯卡拉認爲難以接受的複雜類型之一的例子)。

相關問題