Skip to content

Instantly share code, notes, and snippets.

@ioleo
Created January 26, 2018 12:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ioleo/399d3495f323c9ab8b6a4d1d7d2ff21d to your computer and use it in GitHub Desktop.
Save ioleo/399d3495f323c9ab8b6a4d1d7d2ff21d to your computer and use it in GitHub Desktop.
Arbitrary freestyle free program example with multiple instructions
import cats.data.State
import freestyle.free._
/* domain objects */
case class Id(id: String)
case class AcmeItem(id: Id)
/* state */
trait MapState[K, V] {
type Type = Map[K, V]
type TypeA[A] = State[Type, A]
def apply(state: Map[K, V]): Type = state
def apply(state: (K, V)*): Type = state.toMap
def empty: Type = Map.empty[K, V]
}
object AcmeStorageState extends MapState[Id, AcmeItem]
/* freestyle free */
@free trait AcmeStorage {
def put(item: AcmeItem): FS[Unit]
def get(id: Id): FS[Option[AcmeItem]]
}
object FreeAcme extends App {
implicit val acmeStorageHandler = new AcmeStorage.Handler[AcmeStorageState.TypeA] {
def put(item: AcmeItem): AcmeStorageState.TypeA[Unit] = State.modify(_.updated(item.id, item))
def get(id: Id): AcmeStorageState.TypeA[Option[AcmeItem]] = State.inspect(_.get(id))
}
val (id1, id2, id3) = (Id("foo"), Id("bar"), Id("baz"))
val (item1, item2, item3) = (AcmeItem(id1), AcmeItem(id2), AcmeItem(id3))
val ops = AcmeStorage.to[AcmeStorage.Op]
val inputState = AcmeStorageState.empty
val program = for {
_ <- ops.put(item1)
_ <- ops.put(item2)
_ <- ops.put(item3)
mid <- ops.get(id2)
} yield mid
val (outputState, result) = program.interpret[AcmeStorageState.TypeA].run(inputState).value
val assertion1 = outputState == AcmeStorageState(id1 -> item1, id2 -> item2, id3 -> item3)
val assertion2 = result == Some(item2)
println("%s << outputState == AcmeStorageState(id1 -> item1, id2 -> item2, id3 -> item3)".format(assertion1))
println("%s << result == Some(item2)".format(assertion2))
// true << outputState == AcmeStorageState(id1 -> item1, id2 -> item2, id3 -> item3)
// true << result == Some(item2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment