To avoid traversing the entire list with forall , to check if the entire set of parameters is set, you can use foldLeft and use the fact that you can get None for the first time you find an empty element in the chain.
def sumList(list: List[Option[T]])(implicit ev: Numeric[T]): Option[T] = { list.foldLeft(Option(ev.zero)) { case (acc, el) => el.flatMap(value => acc.map(ac => ev.plus(ac, value))) } } sumList(List(None, None, Some(5))) res10: Option[Int] = None scala> sumList(List(None, None, Some(5F))) res11: Option[Float] = None scala> sumList[Double](List(None, None, None)) res13: Option[Double] = None scala> sumList(List(Some(5), Some(15))) res14: Option[Int] = Some(20)
And to avoid return , you can simply use recursion ( update , return is not required above, but it might be easier to do):
@annotation.tailrec def sumListRec[T](list: List[Option[T]], acc: T)(implicit ev: Numeric[T]): Option[T] = { list match {
Watch the action:
scala> sumListRec(List(Some(5D), Some(5D)), 0D) res5: Option[Double] = Some(10.0) sumListRec(List(None, None, Some(5D)), 0D) res2: Option[Double] = None scala> sumListRec(List(None, None), 0D) res6: Option[Double] = None
source share