Scala 使用隐式将类型参数视为数字
我在以下多态函数定义方面遇到问题:Scala 使用隐式将类型参数视为数字,scala,Scala,我在以下多态函数定义方面遇到问题: 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 sc
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
scala>def foo[A](x:A,y:A)(隐式o:A=>Numeric[A]):A=x+y
:7:错误:类型不匹配;
发现:A
必需:字符串
def foo[A](x:A,y:A)(隐式o:A=>数值[A]):A=x+y
我想指定类型参数
A
可以用作数值
,但它不起作用。我做错了什么?您需要的两个更改是,第一个隐式不应该是从a
到Numeric[a]
的函数,而只是Numeric[a]
,第二个您需要导入Numeric.Implicits
,以获得启用+
的隐式操作
import scala.math.Numeric.Implicits._
def foo[A](x : A, y : A)(implicit num: Numeric[A]) : A = x + y
如果没有导入,您必须将其编写为:
def foo[A](x : A, y : A)(implicit num: Numeric[A]) : A = num.plus(x,y)
Numeric[A]
通常是一个实例,用于访问类型A
上的算术运算。它将包含def plus(x:A,y:A):A
,而不是def add(x:A):A
,后者将包含一些类型为A的this
它类似于java的比较器
(或scala的排序
),它有一个比较(to1,to2)
,而不是java的可比
(scala的排序
),它有一个比较器(tother)
。这些类型,以及隐式可用的单例实现,通常在Haskell语言中的一个密切相关的特性之后被称为TypeClass
所以你不想把A
转换成Numeric[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)
,但是如果导入scala.math.numeric.\u
,您将获得一些魔力和更方便的x+y
关于评论中的问题:自从使用scala(在V2.8上)编程以来,语言是否发生了变化
语法[A:Numeric]
,称为上下文绑定
,在该语言中引入较晚,我不是100%确定,但我相信它在2.8中不可用。但这只是一个隐式数值[a]
参数的快捷方式,在2.8版中是可能的(Numeric
在2.8版中是可用的,实际上是刚刚引入的),当时应该如上图所示使用。除此之外,没有语言变化
然而,在scala的早期,更常见的是使用“视图”,这意味着隐式转换,而不是类型类,也就是说,使用诸如compariable
/Ordered
,而不是Comparator
/Ordering
对于此类类型,通常使用上界A有序[A]
过去有一个快捷方式,[a Ordered[a]
),类型类是首选。原因有很多,例如:
- 在隐式作用域中使用转换函数将充当隐式强制转换,这是非常危险的
- TypeClass功能更强大。例如,您可以拥有
Numeric[A]的实例
即使你周围没有A
的实例,也可以得到A
类型的zero
。如果你在一个列表上调用sum
,而列表是空的,那么Numeric
仍然可用,你可以得到zero
。如果Numeric
是A
实现的东西,即使它是空的adezero
可用时,您将没有可调用的实例。另一个示例是,typeclass可以用作工厂,同样,当您没有构造类型的实例时(尚未),如中所示
引用Martin Odersky()的话:
上下文边界本质上是视图边界的替换
我们从一开始就应该做些什么,但我们并不清楚
当时
谢谢。当我模仿Scala book中编程的一段代码片段时,Typesafe是否更改了隐式的语法?该代码片段定义了一个函数,正如我在文章中所做的。在上面的回复中回答