Advertisement
Guest User

Untitled

a guest
Jul 15th, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.12 KB | None | 0 0
  1. ### FoldLeftSC
  2.  
  3. > A `Foldable.foldLeft`implementation that short-circuits on a given predicate
  4.  
  5. ---
  6.  
  7. The first attempt was a failure. Using `foldM` and `Option`.
  8.  
  9. ```scala
  10. def foldLeft[F[_]: Foldable, A, B](fa: F[A])(b: B)(f: (B, A) => B)(p: B => Boolean): B =
  11. Foldable[F].foldM[Option,A,B](fa, b) {
  12. case (b, a) if !p(b) => none or b.some
  13. case (b, a) => f(b,a).some
  14. }.getOrElse(b)
  15. ```
  16.  
  17. Both implementation did actually not do what we want:
  18.  
  19. - The first one, using none, will short-circuit as expected but will always return none.
  20. - The second one, using some, will accumulate while skipping the elements that do not fulfill the predicate.
  21.  
  22. The solution is use `foldM` but `Either[B,B]` instead of `Option`:
  23.  
  24. ```scala
  25. def foldLeft[F[_]: Foldable, A, B](fa: F[A])(b: B)(f: (B, A) => B)(p: B => Boolean): B =
  26. Foldable[F].foldM[Either[B, ?],A,B](fa, b) {
  27. case (b, a) if !p(b) => b.asLeft
  28. case (b, a) => f(b,a).asRight
  29. } match {
  30. case Left(b) => b
  31. case Righ(b) => b
  32. }
  33.  
  34. // Should return 3
  35. foldLeft(List(1,2,3,4,5))(0)(_ + _)(_ < 3)
  36. // res0: 3
  37. ```
  38.  
  39. Which is actually the same as `traverse` :-)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement