I have a bit of “legacy” Scala code (Java-like), which does a bit of data access. There’s a decorator which tracks usage of the DAO methods (collecting metrics), like this:
class TrackingDao(tracker: Tracker) extends Dao {
def fetchById(id: UUID, source: String): Option[String] = {
tracker.track("fetchById", source) {
actualFetchLogic(...)
}
}
...
}
I'm trying to model this as a Free monad. I've defined the following algebra for the DAO operations:
sealed trait DBOp[A]
case class FetchById(id: UUID) extends DBOp[Option[String]]
...
I see two options:
a) I can either make two interpreters that take DBOp
, one performs the actual data access, the other does the tracking, and compose them together OR
b) I make Tracking an explicit algebra, and use a Coproduct to use them both in the same for
composition OR
c) Something completely different!
The first option looks more like a "decorator" approach, which is tied to DBOp
, the second is more generic solution, but would require calling the 'tracking' algebra explicitly.
In addition, notice the source
parameter on the original fetchById
call: it's only used for tracking. I much rather remove it from the API.
Here's the actual question: how do I model the tracking?