Scala:如何定义“通用”函数参数?

我现在正在尝试学习Scala,并在Haskell中有一些经验。 有一件事对我来说很奇怪,那就是Scala中的所有函数参数都必须使用类型进行注释 - 这是Haskell不需要的。 为什么是这样? 试图把它作为一个更具体的例子:添加函数是这样写的:

def add(x:Double, y:Double) = x + y

但是,这只适用于双打(因为隐式类型转换,因此整数工作也是如此)。 但是如果你想要定义自己的类型来定义自己的+运算符,会发生什么呢? 你将如何编写一个适用于任何定义了+运算符的类型的add函数?


Haskell使用Hindley-Milner类型推理算法,而Scala为了支持面向对象的事物,现在不得不放弃使用它。

为了方便地为所有适用类型编写添加函数,您需要使用Scala 2.8.0:

Welcome to Scala version 2.8.0.r18189-b20090702020221 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import Numeric._
import Numeric._

scala> def add[A](x: A, y: A)(implicit numeric: Numeric[A]): A = 
     | numeric.plus(x, y)
add: [A](x: A,y: A)(implicit numeric: Numeric[A])A

scala> add(1, 2)
res0: Int = 3

scala> add(1.1, 2.2)
res1: Double = 3.3000000000000003

为了巩固我自己使用隐式的概念,我写了一个不需要scala 2.8的例子,但是使用了相同的概念。 我认为这可能对一些人有帮助。 首先,你定义一个通用抽象类Addable:

scala> abstract class Addable[T]{
 |   def +(x: T, y: T): T
 | }
defined class Addable

现在你可以像这样编写add函数:

scala> def add[T](x: T, y: T)(implicit addy: Addable[T]): T = 
 | addy.+(x, y)
add: [T](T,T)(implicit Addable[T])T

这在Haskell中用作类型类。 然后为了实现这个泛型类的特定类型,你会写(例如Int,Double和String的例子):

scala> implicit object IntAddable extends Addable[Int]{
 |   def +(x: Int, y: Int): Int = x + y
 | }
defined module IntAddable

scala> implicit object DoubleAddable extends Addable[Double]{
 |   def +(x: Double, y: Double): Double = x + y
 | }
defined module DoubleAddable

scala> implicit object StringAddable extends Addable[String]{
 |   def +(x: String, y: String): String = x concat y
 | }
defined module StringAddable

此时,您可以使用以下三种类型调用add函数:

scala> add(1,2)
res0: Int = 3

scala> add(1.0, 2.0)
res1: Double = 3.0

scala> add("abc", "def")
res2: java.lang.String = abcdef

当然不如Haskell那么好,它基本上会为你做所有这些事情。 但是,这就是权衡所在。


Haskell使用Hindley-Milner类型推断。 这种类型推理功能强大,但限制了语言的类型体系。 假设,例如,子类化不能很好地处理HM。

无论如何,Scala类型系统对于HM来说太强大了,所以必须使用更为有限的类型推断。

链接地址: http://www.djcxy.com/p/43319.html

上一篇: Scala: How to define "generic" function parameters?

下一篇: Haskell or Standard ML for beginners?