扩展Scala的箭头表示法

时间:2014-06-27 21:04:36

标签: scala

Scala在Predef中定义了对->的支持(此处清理了一下):

final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal {    
    def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y)
    def →[B](y: B): Tuple2[A, B] = ->(y)
}

这样可以方便地使用箭头符号而不是普通元组语法创建对:

scala> "foo" → 42
res0: (String, Int) = (foo,42)

使用类型定义和提取器(此处仅显示)可以轻松扩展此箭头语法:

type →[A, B] = (A, B)
object → { def unapply[A, B](t: (A, B)) = Some(t) }

这允许您编写如下内容:

"a" → 42 match { case a → b ⇒ println(s"found `$a` and `$b`") }

def foo[A, B](t: A → B) = ???

我想知道Scala是否有任何理由不在其标准库中定义它们。这些定义是否有任何缺点?

2 个答案:

答案 0 :(得分:1)

这是一个缺点。能够做到这两点

def foo[A, B](t: A -> B) = ???

def foo[A, B](t: A => B) = ???

会让人感到困惑。如果类型不排队,编译器当然会抓住它。但是,只有经验丰富的Scala程序员才能快速理解错误消息。

答案 1 :(得分:1)

我非常确定->只有一种易于阅读的方式来初始化Map条目。它并不是一种表示对的通用方法。您应该将(a, b)语法用于所有其他用途以避免混淆。实际上,已经有两种不同的方式来表示一对((a, b)Tuple2(a, b))。我们不需要第三个。

你可能会说你想要一个 - >用于对Map条目进行模式匹配的提取器,以明确哪个部分是键,哪个是值,但请记住case (key, value)使这种区别同样明确。仅在初始化的情况下,除了使用->之外,没有明确的方法来区分哪个部分是关键,哪个部分是值。