blue-sky
blue-sky

Reputation: 53826

What determines 'A' type in foldLeft?

In this definition of foldLeft where List of Ints are reversed :

  val l = List(1, 2)                              //> l  : List[Int] = List(1, 2)
  l.foldLeft(List[Int]())((b, a) => a :: b)       //> res2: List[Int] = List(2, 1)

How is A typed to an Int in foldLeft function ?

Source for foldLeft is :

  def foldLeft[B](z: B)(f: (B, A) => B): B = {
    var acc = z
    var these = this
    while (!these.isEmpty) {
      acc = f(acc, these.head)
      these = these.tail
    }
    acc
  }

What determines the A type ? Is there some Scala implicit logic occurring that determines Int type from type parameter List[Int] ?

Update :

foldLeft is defined in LinearSeqOptimized.

When list is created using val l = List(1,2) this also types the A parameter to LinearSeqOptimized as it is part of its object hierarchy :

sealed abstract class List[+A] extends AbstractSeq[A]
                                  with LinearSeq[A]
                                  with Product
                                  with GenericTraversableTemplate[A, List]
                                  with LinearSeqOptimized[A, List[A]]
                                  with Serializable {

This is why type A is typed to Int in foldLeft ?

Upvotes: 2

Views: 949

Answers (2)

Gabriele Petronella
Gabriele Petronella

Reputation: 108121

In a nutshell

List(1, 2, 3).foldLeft(List[Int]())((b, a) => a :: b)
     ^                 ^
     A                 B

Upvotes: 4

Michael Zajac
Michael Zajac

Reputation: 55569

foldLeft[B] is a member of List[A] (and many different collection types). So the A is just the type parameter of the collection you are folding.

List(1, 2) is a List[Int], so A = Int.

B is then the type you are folding into (the return type of fold). It might be the same as A, but it might not. In your example, you are folding into a List[Int], so B = List[Int] (not Int).

Upvotes: 6

Related Questions