Я пытаюсь объединить Writer и State (через объектив). Я уверен, что мне нужны трансформаторы монады, но мне сложно понять, как использовать версии T и как правильно их строить.Scalaz: comb Writer and State (and/or Lens)
Сейчас у меня есть некоторые модели (упрощенные):
case class Schedule(due: LocalDate)
case class Task(title: String, schedule: Schedule)
линза, определенная для каждого поля, titleL
, scheduleL
и dueL
.
Типа псевдоним для моего писателя 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
}
Как я должен подойти к этому? Я на правильном пути с монадными трансформаторами? Что-нибудь еще, что я мог пропустить, уже обрабатывает мое дело?
EDIT:
я получил что-то работает, как это, это нормально для этого случая использования, но я хотел бы кое-что лучше интегрируется с государством для более сложных:
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
}
Как вы сказали, это похоже на то, с чем я закончил, но на самом деле я начинаю открывать, когда узнаю больше, что я, вероятно, не смоделировал все правильно. У меня было ощущение, что RWS появится, хотя я продолжу это в качестве примера, спасибо за это. – wiill