1

I was looking at the type of map for Try[T] in Scala, which is:

def map[S](f: T=>S): Try[S]

From Haskell, I am used to the type of map being:

map :: (a->b)->[a]->[b]

This seems very logical. Map takes a function and a group of elements and applies that function over all elements of the set.

However, I don't understand what the Scala type means. If map transforms Try[S] into Try[T] ,why is the type not:

def map[Try[T]](f:T=>S): Try[S]
7

Scala is an object-oriented language. In object-oriented languages, methods have special access to a designated "receiver" argument (typically called this or self). This parameter is usually not made explicit in the method signature (Python is an exception).

So, you have to remember that the map method is actually defined as a member of a trait or class and that there is an additional invisible zeroth parameter whose type is the type of the class or trait the method is a member of.

In this particular case, the type is Try[T].

So, if map were a free-standing function, its type would be:

def map[S, T](this: Try[T], f: T ⇒ S): Try[S]

which is equivalent to the Haskell type

map :: Try t → (t → s) → Try s
2

There are three parts in this type signature:

  • Current, original type, T
  • Return type, U
  • Transformation, f: (T) => U

Since you're looking at a generic class with a map method (as opposed to just a stand-alone function), the T type variable is defined above, in a class type signature: Try[T]. This explains why there's no T inside bracket of map[...]. It's already there, you don't have to specify it again (and you cannot).

So, simply, Try[T] class signature provides enough context for compiler to know about the source type.

In Haskell, you're dealing with functions, not methods of classes, so you have to state inputs explicitly. There is no this or self in Haskell.


In Scala, letters inside brackets [T] are type variable declarations, whereas in (T) => U they become actual type signatures. Honestly, in cases like this, I think it would be sufficient to just write def map(f: (T) => U): Try[U] (note no brackets after map), but I can't argue with the compiler. You just have to tell the compiler that you're going to use U in the following type signature.

  • Good answer. Note that in Scala, as in Java, generic functions always need to declare their "generic types", regardless of whether they are used in the return type. In the OP's case S is needed, but not T because it's already declared in Try[T]. – Andres F. Jun 4 '16 at 23:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.