Steps in a uniform journey can be mapped over and flatMapped together.
Composing journeys together
A journey is simply a composition of steps (such ask
, tell
, interact
or end
)
using the same semantics as monads such as Option
or List
that you are
already familiar with in Scala.
Lets start with a simple example that collects two Person
records
from a user. We can simply put the two ask
calls together in a for
comprehension.
import ltbs.uniform._
case class Person(name: String, age: Int)
def senderAndReceiver1 = for {
sender <- ask[Person]("sender")
receiver <- ask[Person]("receiver")
} yield (sender, receiver)
This is fine, but if we wanted to ask the user for the name and age separately we would have some duplication in our code.
def senderAndReceiver2 = for {
senderName <- ask[String]("sender-name")
senderAge <- ask[Int]("sender-age")
receiverName <- ask[String]("receiver-name")
receiverAge <- ask[Int]("receiver-age")
} yield (
Person(senderName, senderAge),
Person(receiverName, receiverAge)
)
Fortunately it is easy to create subjourneys and compose them into a larger journey.
We can separate out the collection of the person record into a local function -
def askPerson(id: String) = for {
name <- ask[String](s"$id-name")
age <- ask[Int](s"$id-age")
} yield Person (name, age)
def senderAndReceiver3 = for {
sender <- askPerson("sender")
receiver <- askPerson("receiver")
} yield (sender, receiver)