Sometimes, the effect type that we are going to use is not known in advance. Consider the problem of logging. Logging can be performed to a list or a file. Logging to a list can be implemented using the Writer effect type.
A Writer is an abstraction of a pair of a result and a log generated by a computation. In its simplest form, a Writer can be understood as a pair of a list of strings and an arbitrary result. We can define the Writer effect type as follows:
case class SimpleWriter[A](log: List[String], value: A) {
def flatMap[B](f: A => SimpleWriter[B]): SimpleWriter[B] = {
val wb: SimpleWriter[B] = f(value)
SimpleWriter(log ++ wb.log, wb.value)
}
def map[B](f: A => B): SimpleWriter[B] =
SimpleWriter(log, f(value)
}
Notice that we have also defined the familiar map and flatMap methods for this effect type.
A few words should be said about...