Created
September 15, 2016 13:28
-
-
Save lamdor/777693ee57b3f0389ffb8afafa62bfec to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package learn | |
import java.io.File | |
import cats.{~>, Id} | |
import cats.free.Free | |
import cats.data.Xor | |
import cats.instances.option._ | |
import freek._ | |
import scala.concurrent.Future | |
object Log { | |
sealed trait LogLevel | |
case object DebugLevel extends LogLevel | |
case object InfoLevel extends LogLevel | |
case object WarnLevel extends LogLevel | |
case object ErrorLevel extends LogLevel | |
trait DSL[A] | |
final case class LogMsg(level: LogLevel, msg: String) extends DSL[Unit] | |
def debug(msg: String) = LogMsg(DebugLevel, msg) | |
def info(msg: String) = LogMsg(InfoLevel, msg) | |
def warn(msg: String) = LogMsg(WarnLevel, msg) | |
def error(msg: String) = LogMsg(ErrorLevel, msg) | |
} | |
object KVS { | |
trait DSL[A] | |
final case class Get(key: String) extends DSL[Option[String]] | |
final case class Put(key: String, value: String) extends DSL[Unit] | |
} | |
object FileIO { | |
trait DSL[A] | |
final case class GetFile(path: String) extends DSL[String Xor File] | |
final case class WriteFile(path: String, contents: String) extends DSL[Unit] | |
final case class DeleteFile(path: String) extends DSL[Unit] | |
} | |
object WritingFilesProgram { | |
type PRG = Log.DSL :|: KVS.DSL :|: FileIO.DSL :|: NilDSL | |
val PRG = DSL.Make[PRG] | |
type O = Xor[String, ?] :&: Option :&: Bulb | |
def getAndWrite(path1: String, path2: String): OnionT[Free, PRG.Cop, O, File] = | |
for { | |
aStr <- KVS.Get(path1).freeko[PRG, O] | |
bStr <- KVS.Get(path2).freeko[PRG, O] | |
combinedPath = "combined" | |
_ <- Log.info(s"writing to file '$combinedPath'").freeko[PRG, O] | |
_ <- FileIO.WriteFile(combinedPath, aStr + bStr).freeko[PRG, O] | |
f <- FileIO.GetFile(combinedPath).freeko[PRG, O] | |
} yield f | |
} | |
object MockIdInterpreters { | |
val LogInterpreter = new (Log.DSL ~> Id) { | |
def apply[A](log: Log.DSL[A]): Id[A] = log match { | |
case Log.LogMsg(level, msg) => | |
println(s"$level - ${msg}") | |
} | |
} | |
val KVSInterpreter = new (KVS.DSL ~> Id) { | |
import KVS._ | |
def apply[A](dsl: DSL[A]): Id[A] = dsl match { | |
case Get(key) => Some("mock") | |
case Put(key, value) => () | |
} | |
} | |
val FileIOInterpreter = new (FileIO.DSL ~> Id) { | |
import FileIO._ | |
def apply[A](dsl: DSL[A]): Id[A] = dsl match { | |
case GetFile(path) => Xor.right(new File(path)) | |
case WriteFile(path, contents) => | |
println(s"MOCK - writing '$contents' to '$path'") | |
case DeleteFile(path) => | |
println(s"MOCK - deletintg to '$path'") | |
} | |
} | |
} | |
object UsingMockIdInterpreters extends App { | |
import WritingFilesProgram._ | |
import MockIdInterpreters._ | |
val interpreter = LogInterpreter :&: FileIOInterpreter :&: KVSInterpreter | |
val result: Xor[String, Option[File]] = | |
getAndWrite("path1", "path2") | |
.value | |
.interpret(interpreter) | |
println(s"result = ${result}") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment