gpt4 book ai didi

scala - 使用隐式将类型参数视为数字

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

我在使用以下多态函数定义时遇到问题:

scala> def foo[A](x : A, y : A)(implicit o : A => Numeric[A]) : A = x + y
<console>:7: error: type mismatch;
found : A
required: String
def foo[A](x : A, y : A)(implicit o : A => Numeric[A]) : A = x + y

我想指定类型参数 A 可以用作 Numeric 但它不起作用。我做错了什么?

最佳答案

A Numeric[A]通常是单个实例,可以访问 A 类型的算术运算.它将包含 def plus(x: A, y: A): A , 而不是 def add(x: A): A , 这将有一些 this A型。

它类似于 java 的 Comparator (或 scala 的 Ordering )有一个 Compare(T o1, T o2) , 而不是 java Comparable (scala 的 Ordered )有一个 CompareTo(T other) .这种具有隐式可用的单例实现的类型通常称为类型类,以 Haskell 语言中密切相关的特性命名。

所以你不想转换ANumeric[A] , 你只想要一个 Numeric[A] .你的签名应该是

def foo[A](x: A, y: A)(implicit numeric: Numeric[A])

有一个捷径,就是

def foo[A: Numeric](x: A, y: A)

在方法中foo , 你可以做 numeric.plus(x,y) , 但如果你 import scala.math.Numeric._ ,你会得到一些魔法,而且更方便x + y .


关于评论中的问题:自从使用 scala 编程(在 v 2.8 上)以来,语言发生了变化吗?

语法 [A: Numeric] , 称为 context bound , 在该语言中引入较晚,我不是 100% 确定,但我相信它在 2.8 中不可用。但这只是 implicit Numeric[A] 的捷径参数,这在 2.8 中是可能的(Numeric 在 2.8 中可用 - 实际上刚刚引入),并且当时应该如上所示使用。除此之外,没有语言变化。

然而,在scala的早期,更常见的是使用“ View ”,意思是隐式转换,而不是类型类,即使用类型,例如Comparable。/Ordered , 而不是 Comparator/Ordering/Numeric .

对于此类类型,您通常会使用上限 A <: Ordered[A] .然而,这可能有点过于严格,因为它只有在实现者有先见之明实现 Ordered 的情况下才会起作用。 .您可以解决这个问题,但需要 A可以转换为 Ordered[A],所以 implicit A => Ordered[A] .

曾经有一个快捷方式,[A <% Ordered[A]] ,称为 View 边界。然而,它已被弃用,虽然 View 仍然是可能的( implicit A => Ordered[A] ),但类型类更受欢迎。这有很多原因,例如:

  • 在隐式作用域中使用转换函数将充当隐式转换并且非常危险
  • 类型类更强大。例如,您可以拥有一个 Numeric[A] 的实例即使你没有 A 的实例周围,​​所以得到 zero类型 A .如果你调用sum在列表上且列表为空时,Numeric仍然可用,您可以获得 zero .如果Numeric是由 A 实现的, 即使它做了 zero可用,您将没有实例可以调用它。另一个例子,当你还没有构造类型的实例时,类型类可以用作工厂,如 this answer 中所示。 .

引用 Martin Odersky ( discussing deprecation ):

context bounds are essentially the replacement of view bounds. It's what we should have done from the start, but we did not know better back then

关于scala - 使用隐式将类型参数视为数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30356472/

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