Skip to content

Instantly share code, notes, and snippets.

@ioleo
Last active June 18, 2020 22:47
Show Gist options
  • Save ioleo/f7b88dfb7dffbabd96a49e37307f262f to your computer and use it in GitHub Desktop.
Save ioleo/f7b88dfb7dffbabd96a49e37307f262f to your computer and use it in GitHub Desktop.
Example of free tagless combined handlers for module
import cats.data.IdT
import cats.{~>, Id, Monad}
import freestyle.tagless.logging.LoggingM
import freestyle.tagless._
import sourcecode.{File, Line}
@tagless trait Summer {
def sum(a: Int, b: Int): FS[Int]
}
@module trait Application {
implicit val M: Monad[FS]
import cats.syntax.flatMap._
import cats.syntax.functor._
val logging: LoggingM
val summer: Summer
def program: FS[Int] =
for {
_ <- logging.debug("test1")
_ <- logging.debug("test2")
_ <- logging.debug("test3")
sum <- summer.sum(5, 3)
} yield sum
}
/* handlers */
trait SummerHandler {
implicit val summerHandler = new Summer.Handler[Id] {
def sum(a: Int, b: Int): FS[Int] = a + b
}
}
trait LoggingHandler {
implicit val logHandlerOption: LoggingM.Handler[Option] = new LoggingM.Handler[Option] {
def debug(msg: String, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def debugWithCause(msg: String, cause: Throwable, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def error(msg: String, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def errorWithCause(msg: String, cause: Throwable, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def info(msg: String, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def infoWithCause(msg: String, cause: Throwable, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def warn(msg: String, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
def warnWithCause(msg: String, cause: Throwable, sourceAndLineInfo: Boolean)(implicit line: Line, file: File): Option[Unit] = Some(())
}
}
trait CombinedHandler extends SummerHandler with LoggingHandler {
// given a natural transformation Option ~> Id we can create a new handler for Id from Option handler
implicit val logHandlerId: LoggingM[Id] =
logHandlerOption.mapK(new (Option ~> Id) {
override def apply[A](optionA: Option[A]): Id[A] = IdT.pure(optionA.get).value
})
}
object CombiningTaglessHandlers extends App with CombinedHandler {
val result = Application[Id].program
println(s"result is $result")
// result is 8
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment