trait Algebra[F[_]] {
def readEnv(name: String): F[String]
def readLn: F[String]
def write(output: String): F[Unit]
}
class Program[F[_]: cats.Monad](x: Algebra[F]) {
// `flatMap` extension method
import cats.implicits.toFlatMapOps
// `map` extension method
import cats.implicits.toFunctorOps
def enProgram(): F[Unit] =
for {
<- x.write("What's your name? ")
_ <- x.readLn
name <- x.write(s"Hello, ${name}!\n")
_ } yield ()
def esProgram(): F[Unit] =
for {
<- x.write("¿Cómo te llamas? ")
_ <- x.readLn
name <- x.write(s"¡Hola, ${name}!\n")
_ } yield ()
def program: F[Unit] =
for {
<- x.readEnv("LANG")
lang <- if (lang.startsWith("es")) {
_
esProgram} else {
enProgram}
} yield ()
}
object Interpreter extends Algebra[cats.Id] {
override def readEnv(name: String): cats.Id[String] = sys.env(name)
override def readLn: cats.Id[String] = scala.io.StdIn.readLine()
override def write(output: String): cats.Id[Unit] = print(output)
}
new Program(Interpreter).program
This file is literate Scala, and can be run using Codedown:
$ LANG=es_MX.UTF-8 scala-cli --scala 2.13.10 --dependency org.typelevel::cats-core:2.3.0 \
<(curl https://earldouglas.com/posts/effect-systems/cats.md | codedown scala)
¿Cómo te llamas? James
¡Hola, James!