gpt4 book ai didi

scala - 基于返回类型推断的意外隐式解析

转载 作者:行者123 更新时间:2023-12-03 06:03:25 25 4
gpt4 key购买 nike

给定一个类型类,其中应根据返回类型执行实例选择:

case class Monoid[A](m0: A) // We only care about the zero here
implicit def s[T] : Monoid[Set[T]] = Monoid(Set.empty[T])
implicit def l[T] : Monoid[List[T]] = Monoid(List.empty[T])
def mzero[A](implicit m: Monoid[A]) : A = m.m0

为什么 Scala (2.11.6) 无法解析正确的实例:

scala> mzero : List[Int]
<console>:24: error: ambiguous implicit values:
both method s of type [T]=> Monoid[Set[T]]
and method l of type [T]=> Monoid[List[T]]
match expected type Monoid[A]
mzero : List[Int]
^

当使用隐式函数时,根据返回类型找到隐式没有问题时(我们在这里将其重新定义为i,以说明它与<强>mzero)

def i[A](implicit a : A) : A = a
scala> i : Monoid[List[Int]]
res18: Monoid[List[Int]] = Monoid(List())

错误消息中的 Monoid[A] 而不是 Monoid[List[Int]] 令人费解。

我假设许多 scalaz 贡献者都熟悉这个问题,因为它似乎限制了 scala 中类型类的便利性。

编辑:我正在考虑在不放弃类型推断的情况下使其工作。否则我想了解为什么这是不可能的。如果这个限制被记录为 Scala 问题,我找不到它。

最佳答案

1)按如下方式重写代码后:

case class Monoid[A](m0: A) // We only care about the zero here
implicit def s[T] : Monoid[Set[T]] = Monoid(Set.empty[T])
implicit def l[T] : Monoid[List[T]] = Monoid(List.empty[T])
def mzero[A]()(implicit m: Monoid[A]) : A = m.m0

val zero = mzero[List[Int]]()
val zero2: List[Int] = mzero()

然后就清楚为什么会这样了。

2) 在您必须将 mzero 设置为 def mzero[A]()(implicit m: Monoid[_ <: A]) : A = m.m0 之后然后您启用了附加类型推断来解析存在类型。编译器从所需的返回类型中获取实际类型。您可以通过 def mzero[A <: B, B]()(implicit m: Monoid[A]) : A = m.m0 检查它如果你愿意的话。

3)当然,所有这些行为只是编译器的微妙之处,我认为这种部分情况并不需要深入理解。

关于scala - 基于返回类型推断的意外隐式解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30578220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com