[英]Scala Kittens: implicit Sequencer value doesn't seem to work with context bound syntax
In my understanding the following two functions and their calls should be identical:据我了解,以下两个函数及其调用应该是相同的:
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)
However, the call to f2 doesn't compile:但是,对 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}
The Scala compile seems to expand the type alias Sequencer.Aux in the second case and isn't able to construct a suitable implicit. Scala 编译似乎在第二种情况下扩展了类型别名 Sequencer.Aux 并且无法构造合适的隐式。
If I directly define my function with the expanded type, no implicit can be constructed either:如果我直接用扩展类型定义我的 function ,也不能构造隐式:
def f3[L1 <: HList, L2](xs: L1)(implicit sequencer: Sequencer[L1]{type F[X] = Option[X]; type LOut = L2}) {
println(xs.sequence)
}
Apart from the inconvenience of not being able to use the more compact context bound syntax there are two things that I don't understand about this situation:除了无法使用更紧凑的上下文绑定语法带来的不便外,我对这种情况还有两件事不明白:
type Aux[L <: HList, F0[_], LOut0] = Sequencer[L] {
type F[X] = F0[X]
type LOut = LOut0
}
I would have expected both types to behave identical.我本来希望这两种类型的行为相同。
Looks like a bug.看起来像一个错误。 Bugs should be reported here: https://github.com/scala/bug/issues
应在此处报告错误: https://github.com/scala/bug/issues
I tried to create minimal example.我试图创建最小的例子。
And maybe I oversimplified the example but now I have issues even with
HNil
case.
也许我过度简化了这个例子,但现在即使是
HNil
案例我也遇到了问题。
For为了
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]]
compiles but implicitly[Sequencer[HNil]{type F[X] = Option[X]}]
doesn't and there is warning ( scalacOptions += "-Xlog-implicits"
) 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]]
And probably here we can see the reason: could not find implicit value for parameter F: cats.Applicative[Option[X]]
should be could not find implicit value for parameter F: cats.Applicative[Option]
.可能在这里我们可以看到原因:
could not find implicit value for parameter F: cats.Applicative[Option[X]]
应该could not find implicit value for parameter F: cats.Applicative[Option]
。
But for some reason if I remove implicit F: Applicative[F0]
then for但是由于某种原因,如果我删除
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]]
doesn't compile although implicitly[Sequencer.Aux[HNil, Option]](Sequencer.nil())
compiles.尽管
implicitly[Sequencer.Aux[HNil, Option]](Sequencer.nil())
编译,但隐式implicitly[Sequencer.Aux[HNil, Option]]
不会编译。
implicitly[Sequencer[HNil]{type F[X] = Option[X]}]
doesn't compile either. implicitly[Sequencer[HNil]{type F[X] = Option[X]}]
也不编译。 And if we write implicitly[Sequencer[HNil]{type F[X] = Option[X]}](Sequencer.nil())
we'll see why如果我们
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
shows that this is a bug.
... has one type parameter, but... has one
表明这是一个错误。
Bug tracker shows open issues for "implicit" and "higher-kind"错误跟踪器显示“隐式”和“高级”的未解决问题
https://github.com/scala/bug/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+implicit+higher-kind 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.