Slide 39
Slide 39 text
© 2024 Loglass Inc. 39
04 | Applying the Language: Fiscal Periods
Implementing the Semantics with Logging
final case class EvalWithLog(startMonth: Int) extends FiscalPeriodSym:
type Repr[A] = (List[String], A)
…
def quarter(n: Int, q: Int): Repr[Quarter] =
val m = ((startMonth + 3 * (q - 1) - 1) % 12) + 1
val start = LocalDate.of(n, m, 1)
val end = start.plusMonths(3).minusDays(1)
(List(s"quarter($n, $q)"), Quarter(Period(start, end)))
…
def union[A, B](p1: Repr[A], p2: Repr[B])(using IsPeriod[A], IsPeriod[B]): Repr[Period] =
val (l1, v1) = p1
val (l2, v2) = p2
val a = summon[IsPeriod[A]].toPeriod(v1)
val b = summon[IsPeriod[B]].toPeriod(v2)
val r = Period(a.start min b.start, a.end max b.end)
(l1 /+ l2 :+ s"union(${a.start}–${a.end}, ${b.start}–${b.end}) = ${r.start}–${r.end}", r)
…
The user program stays clean —
and yet we can log every step for debugging.