I want to fold a collection or Y's and return an Option[X]. I want to start with None. Like this...
def f(optX: Option[X], y: Y): Option[X]
val optX = collectionOfY.fold(None) { case (prev, y) => f(prev,y) }
adding unneeded types to make it clearer
val optX: Option[X] = collectionOfY.fold(None) { case (prev: Option[X], y: Y) => f(prev,y) }
However, the compiler can not figure out the type properly and I have to write it like this
val xx: Option[X] = None
val optX = collectionOfY.fold(xx) { case (prev, y) => f(prev,y) }
What is the magic Scala syntax to write this?
Thanks Peter
Just use foldLeft
and any of the following
... foldLeft(Option.empty[X]) ...
or ... foldLeft(None: Option[X]) ...
or ... foldLeft[Option[X]](None) ...
After all, fold
just calls foldLeft
. You only really want to use fold
when your A1
really is a super-type of A
, if that really is the case then you can use fold
as above and the compiler will know the type correctly.
For example, Option[List[Int]] <: Option[Seq[Int]]
by covariance so we don't get an Any
here:
List(Some(List(1,2,3))).fold[Option[Seq[Int]]](None)((_, _) => Some(Seq(1)))
> res2: Option[Seq[Int]] = Some(List(1))
Finally, if you do indeed know Option[X]
will be a super-type of Y
then say this explicitly in the type declaration of Y
- i.e. Y <: Option[X]
, then you can use fold
with the solutions given above.
See When should .empty be used versus the singleton empty instance? for a related discussion.