Alex Rivera | Logout

Is it feasible to use type members to reduce type verbosity in Scala?

Asked 2012-07-08T03:00:08.933
13

So, this may sound like a general question about language design, but I think there is something concrete here. Specifically I am interested in what technical challenges prevent the kludgy code that follows from being generally useful.

We all know that "Scala's type inference isn't as good as Haskell's", and that there are many reasons it just can't be as good, and still do all the things Scala does. But what also becomes apparent, after programming Scala long enough, is that poor type inference isn't really that bad, so much as is the verbosity that is required to specify some common types. So, for example, in the polymorphic tail function,

def tail[A](ls: List[A]) =
    ls match {
        case Nil     => sys.error("Empty list")
        case x :: xs => xs
    }

it is required to explicitly name a type parameter in order to make the method useful; no way around it. tail(ls: List[Any]) won't work because Scala can't figure out that the result type is the same is the input type, even though to a human this is "obvious".

So, inspired by this difficulty, and knowing that Scala can sometimes be cleverer with type members than with type parameters, I wrote a version of List that uses type members:

sealed trait TMList {
    self =>
    type Of
    def :::(x: Of) = new TMCons {
        type Of = self.Of
        val head = x
        val tail = (self: TMList { type Of = self.Of })
    }
}
abstract class TMNil extends TMList
def ATMNil[A] = new TMNil { type Of = A }
abstract class TMCons extends TMList {
    self =>
    val head: Of
    val tail: TMList { type Of = self.Of }
}

OK, the definition looks awful, but it is at least straightforward, and it allows us to write our tail method as follows:

def tail4(ls: TMList) =
    ls match {
        case _: TMNil => sys.error("Empty list")
        c
Edit
Report

1 Answer

6

You will want to read type refinements do everything.

answered 2012-07-08T05:10:09.527

Your Answer