views:

208

answers:

3

It does not look very good for me to always repeat a line-long tuple definition every time I need it. Can I just name it and use as a type name? Would be nice to name its fields also instead of using ._1, ._2 etc.

+15  A: 

Regarding your first question, you can simply use a type alias:

type KeyValue = (Int, String)

And, of course, Scala is an object-oriented language, so regarding your second about how to specialize a tuple, the magic word is inheritance:

case class KeyValue(key: Int, value: String) extends (Int, String)(key, value)

That's it. The class doesn't even need a body.

val kvp = KeyValue(42, "Hello")
kvp._1    // => res0: Int    = 42
kvp.value // => res1: String = "Hello"

Note, however, that inheriting from case classes (which Tuple2 is), is deprecated and may be disallowed in the future. Here's the compiler warning you get for the above class definition:

warning: case class class KV has case class ancestor class Tuple2. This has been deprecated for unduly complicating both usage and implementation. You should instead use extractors for pattern matching on non-leaf nodes.

Jörg W Mittag
+10  A: 

Type alias is fine for naming your Tuple, but try using a case class instead. You will be able to use named parameters

Example with tuple:

def foo(a : Int) : (Int, String) = {
  (a,"bar")
}
val res = foo(1)
val size = res._1
val name= res._2

With a case class:

case class Result( size : Int , name : String )
def foo(a : Int) : Result = {
  Result(a,"bar")
}
val res = foo(1)
val size = res.size
val name= res.name
Steve Gury
Don't tuples work faster than case classes? The task is complex processing of large amounts of simple data, a kind of number-crunching.
Ivan
@Ivan: Tuples *are* case classes, are they not?
Jörg W Mittag
Tuples are indeed case classes!
Randall Schulz
+3  A: 

Here's a solution that creates a type alias and a factory object.

scala> type T = (Int, String)                          
defined type alias T

scala> object T { def apply(i: Int, s: String): T = (i, s) }
defined module T

scala> new T(1, "a")
res0: (Int, String) = (1,a)

scala> T(1, "a")
res1: (Int, String) = (1,a)

However as others have mentioned, you probably should just create a case class.

retronym