Using explicit type parameters when calling function

I came across this code and I am not sure why we need and what it mean [Option[List[A]]] in sequence function

def map2[A,B,C](a: Option[A], b: Option[B])(f: (A, B) => C): Option[C] =
(a,b) match {
case (_, None) => None
case (None, _) => None
case (Some(a2),Some(b2)) => Some(f(a2,b2))
}

def sequence_1[A](a: List[Option[A]]): Option[List[A]] =
a.foldRight[Option[List[A]]]((x,y) => map2(x,y)(_ :: _))

I guess the code is incorrect. Correct is with (Some(Nil))

def sequence_1[A](a: List[Option[A]]): Option[List[A]] =
  a.foldRight[Option[List[A]]](Some(Nil))((x,y) => map2(x,y)(_ :: _))

Try to remove [Option[List[A]]] and you’ll see

type mismatch;
 found   : Option[List[A]]
 required: Some[scala.collection.immutable.Nil.type]

Alternative fix is with type ascription

def sequence_1[A](a: List[Option[A]]): Option[List[A]] =
  a.foldRight(Some(Nil): Option[List[A]])((x,y) => map2(x,y)(_ :: _))

The thing is that the types of Nil and Some(Nil) are inferred too precise: Nil.type and Some[Nil.type] rather than List[A] and Option[List[A]] correspondingly.

.foo[X](...) is a syntax to specify explicitly type parameters of a method (if type parameters can be inferred correctly, [...] can be omitted).

1 Like

foldRight takes two parameters: scala doc

The invocation of foldRight is missing the first parameter, the start value ‘z’. As @DmytroMitin said, the parameter you need is Some(Nil):

If you are interested in the sequence function, you might want to check out this: https://www.slideshare.net/pjschwarz/sequence-and-traverse-part-1 (download for best quality).