[英]Scala Kittens: implicit Sequencer value doesn't seem to work with context bound syntax
據我了解,以下兩個函數及其調用應該是相同的:
def f1[L1 <: HList, L2](xs: L1)(implicit sequencer: Sequencer.Aux[L1, Option, L2]) {
println(xs.sequence)
}
def f2[L1 <: HList : Sequencer.Aux[*, Option, L2], L2](xs: L1) {
println(xs.sequence)
}
f1[Option[Int] :: Option[String] :: HNil, Int :: String :: HNil](Some(42) :: Some("foo") :: HNil)
f2[Option[Int] :: Option[String] :: HNil, Int :: String :: HNil](Some(42) :: Some("foo") :: HNil)
但是,對 f2 的調用無法編譯:
could not find implicit value for evidence parameter of type cats.sequence.Sequencer[Option[Int] :: Option[String] :: shapeless.HNil]{type F[X] = Option[X]; type LOut = Int :: String :: shapeless.HNil}
Scala 編譯似乎在第二種情況下擴展了類型別名 Sequencer.Aux 並且無法構造合適的隱式。
如果我直接用擴展類型定義我的 function ,也不能構造隱式:
def f3[L1 <: HList, L2](xs: L1)(implicit sequencer: Sequencer[L1]{type F[X] = Option[X]; type LOut = L2}) {
println(xs.sequence)
}
除了無法使用更緊湊的上下文綁定語法帶來的不便外,我對這種情況還有兩件事不明白:
type Aux[L <: HList, F0[_], LOut0] = Sequencer[L] {
type F[X] = F0[X]
type LOut = LOut0
}
我本來希望這兩種類型的行為相同。
看起來像一個錯誤。 應在此處報告錯誤: https://github.com/scala/bug/issues
我試圖創建最小的例子。
也許我過度簡化了這個例子,但現在即使是
HNil
案例我也遇到了問題。
為了
import cats.Applicative import shapeless.{::, HList, HNil} import cats.instances.option._ trait Sequencer[L <: HList] extends Serializable { type F[_] } object Sequencer { type Aux[L <: HList, F0[_]] = Sequencer[L] { type F[X] = F0[X] } implicit def nil[F0[_]]( implicit F: Applicative[F0] ): Aux[HNil, F0] = null }
implicitly[Sequencer.Aux[HNil, Option]]
編譯但implicitly[Sequencer[HNil]{type F[X] = Option[X]}]
沒有並且有警告( scalacOptions += "-Xlog-implicits"
)
//Information: App.this.Sequencer.nil is not a valid implicit value for App.Sequencer[shapeless.HNil]{type F[X] = Option[X]} because: //hasMatchingSymbol reported error: could not find implicit value for parameter F: cats.Applicative[Option[X]]
可能在這里我們可以看到原因: could not find implicit value for parameter F: cats.Applicative[Option[X]]
應該could not find implicit value for parameter F: cats.Applicative[Option]
。
但是由於某種原因,如果我刪除implicit F: Applicative[F0]
那么對於
import shapeless.{::, HList, HNil} trait Sequencer[L <: HList] extends Serializable { type F[_] } object Sequencer { type Aux[L <: HList, F0[_]] = Sequencer[L] { type F[X] = F0[X] } implicit def nil[F0[_]](): Aux[HNil, F0] = null }
盡管implicitly[Sequencer.Aux[HNil, Option]](Sequencer.nil())
編譯,但隱式implicitly[Sequencer.Aux[HNil, Option]]
不會編譯。
implicitly[Sequencer[HNil]{type F[X] = Option[X]}]
也不編譯。 如果我們implicitly[Sequencer[HNil]{type F[X] = Option[X]}](Sequencer.nil())
我們就會明白為什么
//Error: inferred kinds of the type arguments (Option[X]) do not conform to the expected kinds of the type parameters (type F0). //Option[X]'s type parameters do not match type F0's expected parameters: //class Option has one type parameter, but type F0 has one
... has one type parameter, but... has one
表明這是一個錯誤。
錯誤跟蹤器顯示“隱式”和“高級”的未解決問題
https://github.com/scala/bug/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+implicit+higher-kind
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.