【发布时间】:2011-06-19 00:40:18
【问题描述】:
在 Haskell 中你可以写:
x :: (Int,Int) -> Int
x (p,s) = p
在 Scala 中你会这样写:
def x(a: (Int, Int)) = a._1
或:
def x(a: (Int, Int)) = a match {
case (p, s) => p
}
为什么没有类似的东西
def x(_: (p: Int, s: Int)) = p
或
def x(foo: (p @ Int, s @ Int)) = p
?
【问题讨论】:
-
如果你只能有 one 方法定义,那么这种模式匹配不会很有用。您需要像 Haskell 中这样的多个定义才能使其真正有用,而这会极大地改变语言的结构。
-
为了澄清@Landei 的评论,Haskell 不允许函数的多个定义。它只是为模式匹配提供了很好的糖。在 Scala 术语中,就好像你可以写 "def f[A](Some(p : A), alt : A) = p;def f(None, alt : A) = alt" 而不是 "def f(x : Option[A], alt : A) = x match { case Some(p) => p; case None => alt}"。不幸的是,Scala 具有 Java 风格的重载,并通过子类型化处理代数数据类型,这两者都会产生歧义。
-
@James Iry:是的,我知道从技术上讲,Haskell 中的“多重定义”只是隐藏了
case ... of语句。但从用户的角度来看,这只是一个实现细节。 -
@Landei 转换成 case 表达式是一个实现细节。但是它们不是多重定义的概念并不是实现细节。鉴于 f 只有一种类型,并且 f 的所有模式必须与 f 的一种类型一致,这在用户面前。
-
@James Iry:虽然我认为从上下文中可以清楚地看出我们不是在谈论重载函数,但我同意称其为“多重定义”是草率的。但更好的术语是什么?诸如“基于模式匹配的调度”之类的东西?但这听起来很荒谬。
标签: scala parameters tuples iterable-unpacking