/
Example.scala
42 lines (35 loc) · 1.27 KB
/
Example.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package freetocompose.example
import scala.language.higherKinds
import cats.instances.function._
import Console.composing._, ConsoleOps.ConsoleOp
import Store.composing._, StoreOps.StoreOp
object Example {
def ask[F[_]: Console](prompt: String) = for {
_ <- print(prompt)
in <- readln()
} yield in
def askForName[F[_]: Console: Store] = for {
name <- ask("Welcome, please enter your name:")
_ <- put("name", name)
} yield name
private val rooms = (100 to 200).map(_.toString)
def nextRoom[F[_]: Store] = for {
roomOpt ← get("lastRoom")
room = roomOpt.fold(rooms.head)((r: String) ⇒ rooms.dropWhile(_ != r).drop(1).head)
_ ← put("lastRoom", room)
} yield room
def assignRoom[F[_]: Console: Store] = for {
name <- askForName
room <- nextRoom
_ <- println(s"Hi $name, you have been assigned room $room")
} yield ()
def main(args: Array[String]): Unit = {
//We'll use trampoline, but anything like scalaz.Task will do (and be a better choice in real applications.
val compiler = ConsoleCompile.toTrampoline || StoreCompile.toTrampoline()
val program = assignRoom[compiler.From].foldMap(compiler)
scala.Console.println("Run 1\n=====")
program.run
scala.Console.println("-----\nRun 2\n=====")
program.run
}
}