Skip to content

Instantly share code, notes, and snippets.

@fancellu
Created October 15, 2019 18:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fancellu/dd4488d82f3ac86434c6a4e34790817d to your computer and use it in GitHub Desktop.
Save fancellu/dd4488d82f3ac86434c6a4e34790817d to your computer and use it in GitHub Desktop.
Example usage of the Cats Foldable FoldM function
import cats._
import cats.data._
import cats.implicits._
// Example usage of the Cats Foldable FoldM function
object FoldableFoldMExample extends App{
def addIfNotTooBig(acc: Int, x: Int): Option[Int] = if (x > 8) none[Int] else (acc + x).some
//FoldM does a stack safe left fold from source context to target monad
// In this case source context is List[Int], target is Option[Int]
// so if you try to fold into a None, you get None, this is why returning None above also returns None
val out=(List(1, 9, 2, 3).foldM(0)(addIfNotTooBig))
println(out)
val out2=(List(1, 7, 2, 3).foldM(0)(addIfNotTooBig))
println(out2)
def parseInt(x: String): Either[Throwable, Int] = Either.catchNonFatal(x.toInt)
def processStrings(list: List[Double], string: String): Either[Throwable, List[Double]] =
(list, string) match {
// as we see operators we take 2 most recent numbers from the list and process
case (x :: y :: tail, "+") => println("+");Either.right((y + x) :: tail)
case (x :: y :: tail, "-") => println("-");Either.right((y - x) :: tail)
case (x :: y :: tail, "*") => println("*");Either.right((y * x) :: tail)
// as we see digits we add them to front of list
case (xs, number) => println(s"prepend $number");parseInt(number).map(_ :: xs)
}
def solve(string: String): Either[Throwable, Double] = for {
List(x) <- (string.split(' ').toList.foldM(Nil: List[Double]){processStrings})
} yield x
println("calculator ok")
println(solve("11 3 4 + 3 * -"))
println("calculator bad")
println(solve("11s 3 4 + 3 * -"))
// works on any foldable, list, option, etc
val exists: Option[Boolean] =List(1,2,3).existsM(i=>(i>2).some)
println(exists)
val exists2: List[Boolean] =List(1,2,3).existsM(i=>List(i>2))
println(exists2)
val exists3: List[Boolean] =3.some.existsM(i=>List(i>2))
println(exists3)
}
None
Some(13)
calculator ok
prepend 11
prepend 3
prepend 4
+
prepend 3
*
-
Right(-10.0)
calculator bad
prepend 11s
Left(java.lang.NumberFormatException: For input string: "11s")
Some(true)
List(true)
List(true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment