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).