Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala type parameter bracket

Tags:

scala

I know trait Foo[T] means T is a parametrized type. But some times I can see trait Foo[T1,T2], or trait Foo[T1,T2,R], I cannot find anywhere describe the meaning of multiple types inside a type bracket, could you please point me the usages in this case? From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.

When I read playframework documentation today, I again found myself confused about this question. In the documentation, it says:

A BodyParser[A] is basically an Iteratee[Array[Byte],A], meaning that it receives chunks of bytes (as long as the web browser uploads some data) and computes a value of type A as result.

This explanation sounds like, the second the type parameter inside a type bracket is a return type.

I also remember that trait Function2 [-T1, -T2, +R] extends AnyRef means a function that takes a T1 and T2, return a R.

Why do they put the return type in the bracket? Does it mean all the last parameter in a bracket is a return type? Or they just happened defined a new type R for the return type?

like image 525
Sawyer Avatar asked Mar 18 '11 16:03

Sawyer


1 Answers

From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.

A type parameter means nothing more than "I need any type but I'm not interested to know what it is for a concrete type", where 'I' is the programmer who writes the code. Type parameters can used like any other types such as Int, String or Complex - the only difference is that they are not known until one uses them.

See type Map[A, +B]. When you first read this, you can't know what the A and B are for, thus you have to read the documentation:

A map from keys of type A to values of type B.

It explains the types and their meaning. There is nothing more to know or understand. They are just two types. It is possible to call Map something like Map[Key, Value] but inside of source code it is better when type parameters have only one or two letters. This makes it easier to differ between the type parameters and concrete types.

It is the documentation which specifies what a type parameter means. And if there is no documentation you have to take a look to the sources and find their meaning by yourself. For example you have to do this with Function2 [-T1, -T2, +R]. The documentation tells us only this:

A function of 2 parameters.

Ok, we know that two of the three type parameters are parameters the function expects, but what is the third one? We take a look to the sources:

def apply(v1: T1, v2: T2): R

Ah, now we know that T1 and T2 are the parameters and that R is a return type.

Type parameters also can be found in method signatures like map:

class List[+A] {
  ..
  def map[B](f: (A) ⇒ B): List[B]
}

This is how map looks like when you use it with a List. A can be any type - it is the type of the elements a list contains. B is another arbitrary type. When you know what map does then you know what B does. Otherwise you have to understand map before. map expects a function which can transform each element of a List to another element. Because you know that A stands for the elements of the List you can derive from yourself that B have to be the type A is transformed to.

To answer all your other questions: This shouldn't be done in a single answer. There are a lot of other questions and answers on StackOverflow which can also answer your questions.

Summary

When you see some type parameters for example in Foo[T1, T2] you should not start to cry. Think: "Ok, I have a Foo which expects a T1 and a T2 and if I want to know what they do I have to read documentation or the sources."

like image 58
kiritsuku Avatar answered Oct 04 '22 22:10

kiritsuku