blue-sky
blue-sky

Reputation: 53786

Explanation of Scala map function signature?

This code applies a function to List of Ints and sets each value in the List of Option with value 4 :

  val l = List(1,2,3,4,5)                         //> l  : List[Int] = 
  val v = 4                                       //> v  : Int = 4
  def g(v:Int) = List(v-1, v, v+1)                //> g: (v: Int)List[Int]
 l map (x => {f(x);})                            //> res0: List[Option[Int]] = List(Some(4), Some(4), Some(4), Some(4), Some(4)) 

Signature of map :

   def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {

Since B is the first type parameter (in map[B, That]) does this mean its typed to the prefix operand 'l' (List) ?

How is 'A' typed ? Does the scala compiler somehow check the type within the the List 'l' and infer that its of type Int ?

How is 'That' typed ?

Upvotes: 2

Views: 4337

Answers (1)

pagoda_5b
pagoda_5b

Reputation: 7373

The simple signature for map in a List[A] is

def map[B](f: (A) ⇒ B): List[B]

which means that

  • A is determined by the type parameter of the actual list
    • Int for the example list l
  • B is determined by the target type of the function f passed as argument
    • Option[Int] for the example function f: Int -> Option[Int]

The expanded signature is

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

which exist so that you can generically map between containers that can be traversed in some way, even when the target traversable has a different form than the original.

A specific example is traversing a Map as a container of Pairs, with a mapping function that produces single values. The resulting traversable is not a Map anymore, so the CanBuildFrom implicit parameter is used to find "available representations" for the resulting object.

In this signature we have

  • Repr as the type of the original traversed container
  • B as the target type of the contained values, as in the simplified signature
  • That as the type of the target container, determined by the implicit existence of a CanBuildFrom with the correct types at call site

Upvotes: 11

Related Questions