我将尝试结合Writer和State(通过Lens)。我很确定需要使用单子变换器,但我很难弄清楚如何使用T版本以及如何正确构建此应用。
目前我有一些模型(简化版):
目前我有一些模型(简化版):
case class Schedule(due: LocalDate)
case class Task(title: String, schedule: Schedule)
为每个字段定义了镜头:titleL
,scheduleL
和dueL
。
我的Writer类型别名为type Logger[A] = Writer[Vector[String], A]
还有一些修改我的模型的函数:
def changeTitle(title: String): Task => Logger[Task] = { t: Task =>
for {
a <- titleL.set(t, title).point[Logger]
_ <- ("Title changed to " + a.title).point[Vector].tell whenM (a.title != t.title)
} yield a
}
def changeDue(date: LocalDate): Schedule => Logger[Schedule] = { s: Schedule =>
for {
a <- dueL.set(s, date).point[Logger]
_ <- ("Due changed to " + a.due).point[Vector].tell whenM (a.due != s.due)
} yield a
}
然而,现在我不确定如何使用该函数的镜头或状态方法。
我希望能够做到类似于这样的事情:
def reschedule(date: LocalDate): Task => Logger[Task] = { t: Task =>
(for {
a <- scheduleL %= reschedule(date)
_ <- ("Reschedule: " + a.schedule).point[Vector].tell whenM (a.schedule != t.schedule)
} yield a) exec t
}
我该如何处理这个问题?使用单子变换器是否正确?还有其他已经处理过我这种情况的方法吗?
编辑:
我已经实现了一些类似这样的东西,对于那个用例来说很好,但是我想要更好地与状态集成以处理更复杂的情况:
def reschedule(date: LocalDate): Task => Logger[Task] = { t: Task =>
for {
sa <- scheduleL.get(t).point[Logger]
sb <- changeDue(date)(sa)
a <- scheduleL.set(t, sb).point[Logger]
_ <- ("Reschedule: " + a.schedule).point[Vector].tell whenM (a.schedule != t.schedule)
} yield a
}