簡體   English   中英

Scala 小貓:隱式 Sequencer 值似乎不適用於上下文綁定語法

[英]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)
}

除了無法使用更緊湊的上下文綁定語法帶來的不便外,我對這種情況還有兩件事不明白:

  1. 為什么只有在我使用上下文綁定語法時才會擴展隱含的證據類型? (兩種語法之間是否存在更多語義差異?)
  2. 為什么 Scala 無法為擴展案例構造合適的隱式? 畢竟,Sequencer.Aux 只是這樣定義的類型別名:
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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM