Created
January 21, 2018 20:11
-
-
Save radium226/df24e0c12a9a7e1fa4322596ea4feb33 to your computer and use it in GitHub Desktop.
Free Monad in Scala with Cats
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
object ImageApp extends App { | |
import cats._ | |
import cats.free._ | |
import cats.data._ | |
case class Image(bytes: Array[Byte]) | |
sealed trait ImageOp[A] // Image Algebra | |
case class Open[A](url: String) extends ImageOp[Image] | |
case class Grayscale[A]() extends ImageOp[Unit] | |
case class Resize[A](ratio: Double) extends ImageOp[Unit] | |
type ImageOpF[A] = Free[ImageOp, A] | |
object ImageOps { | |
def open(url: String): ImageOpF[Image] = Free.liftF[ImageOp, Image](Open(url)) | |
def grayscale: ImageOpF[Unit] = Free.liftF[ImageOp, Unit](Grayscale()) | |
def resize(ratio: Double): ImageOpF[Unit] = Free.liftF[ImageOp, Unit](Resize(ratio)) | |
} | |
val imageOpCompiler = new (ImageOp ~> Id) { | |
def apply[A](imageOp: ImageOp[A]): Id[A] = { | |
imageOp match { | |
case Grayscale() => | |
println("Converting image to grayscale") | |
() | |
case Open(url) => | |
println(s"Opening ${url}") | |
Image(null) | |
case Resize(ratio) => | |
println(s"Resizing image by ${ratio} percent") | |
() | |
} | |
} | |
} | |
import ImageOps._ | |
val program: ImageOpF[Unit] = for { | |
_ <- open("http://tagueule") | |
_ <- grayscale | |
u <- resize(0.5) | |
} yield u | |
val compiled = program.compile(imageOpCompiler).run | |
println(compiled) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment