Created
October 15, 2019 18:05
-
-
Save fancellu/dd4488d82f3ac86434c6a4e34790817d to your computer and use it in GitHub Desktop.
Example usage of the Cats Foldable FoldM function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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