Scala, in Predef
, defines support for ->
and →
(here cleaned up a bit):
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)
}
This conveniently allows you to create pairs using an arrow notation instead of the plain tuple syntax:
scala> "foo" → 42
res0: (String, Int) = (foo,42)
This arrow syntax can easily be extended with a type definition and an extractor (here only →
is shown):
type →[A, B] = (A, B)
object → { def unapply[A, B](t: (A, B)) = Some(t) }
This allows you to write things like:
"a" → 42 match { case a → b ⇒ println(s"found `$a` and `$b`") }
and:
def foo[A, B](t: A → B) = ???
I am wondering if there any reason Scala doesn't define those as well in its standard library. Are there any downsides to these definitions?
I'm pretty sure ->
only exists to have an easy to read way to initialize Map
entries. It's not intended to be a general purpose way to represent pairs. You should use (a, b)
syntax for all other uses to avoid confusion. As it is, there are already two different ways to represent a pair ((a, b)
and Tuple2(a, b)
). We don't need a third.
You might argue that you would want a -> extractor for doing pattern matching on Map
entries to make it clear which part is the key and which is the value, but remember that case (key, value)
makes that distinction just as clear. It's only in the case of initialization that there isn't a clear way to distinguish which part is the key and which is the value, other than using ->
.
Here is one downside. Being able to do both
def foo[A, B](t: A -> B) = ???
and
def foo[A, B](t: A => B) = ???
would be confusing. If the types don't line up, the compiler would catch it of course. However, only a experienced Scala programmer would understand the error message quickly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With