Last active
September 14, 2018 09:16
-
-
Save mmenestret/09796f1de242bcf881b0089b484f2abd to your computer and use it in GitHub Desktop.
Creation of a MonadT for Log
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
case class LoggingT[F[_], A]( | |
run: List[String] => F[(List[String], A)]) { self => | |
def map[B](f: A => B)(implicit F: Functor[F]): LoggingT[F, B] = | |
LoggingT[F, B](log => self.run(log).map(t => (t._1, f(t._2)))) | |
def flatMap[B](f: A => LoggingT[F, B])(implicit F: Monad[F]): LoggingT[F, B] = | |
LoggingT[F, B](log => self.run(log).flatMap(t => f(t._2).run(t._1))) | |
def eval(implicit F: Functor[F]): F[(List[String], A)] = run(Nil).map(t => (t._1.reverse, t._2)) | |
} | |
object LoggingT { | |
def point[F[_]: Applicative, A](a: => A): LoggingT[F, A] = LoggingT(log => Applicative[F].point((log, a))) | |
def lift[F[_], A](fa: F[A])(implicit F: Functor[F]): LoggingT[F, A] = | |
LoggingT(log => fa.map(a => (log, a))) | |
implicit def LoggingTMonad[F[_]: Monad]: Monad[LoggingT[F, ?]] = | |
??? | |
def log[F[_]: Applicative](line: String): LoggingT[F, Unit] = | |
LoggingT(log => Applicative[F].point((line :: log, ()))) | |
} | |
def getName[F[_]: Console: Monad]: F[String] = | |
(for { | |
_ <- LoggingT.lift[F, Unit](Console.putStrLn("Hello, what is your name?")) | |
_ <- LoggingT.log[F]("My log line") | |
n <- LoggingT.lift[F, String](Console.getStrLn) | |
_ <- LoggingT.lift[F, Unit](Console.putStrLn("Good to meet you, " + n + "!")) | |
} yield n).eval.flatMap { | |
case (log, name) => | |
val lines = log.mkString("\n") | |
Console.putStrLn(s"Logging: \n${lines}").map(_ => name) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment