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.
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 ancestorclass Tuple2
. This has been deprecated for unduly complicating both usage and implementation. You should instead use extractors for pattern matching on non-leaf nodes.
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
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.