scalabook
Функциональный журнал
Writer
предназначен для результатов, к которым присоединено другое значение, действующее как своего рода журнал.
Одним из распространенных применений для Writers
является запись последовательностей шагов в многопоточных вычислениях,
где стандартные методы императивной регистрации могут привести к чередованию сообщений из разных контекстов.
При этом лог для вычислений Writer
привязан к результату,
поэтому можно запускать параллельные вычисления без смешивания логов.
final case class Writer[W, A](run: () => (W, A))
Функции общего назначения, описывающие шаблоны программ с ведением журнала
object Writer: extension [W, A](underlying: Writer[W, A]) def map[B](f: A => B): Writer[W, B] = val (w, a) = underlying.run() Writer[W, B](() => (w, f(a)))
def flatMap[B](f: A => Writer[W, B])(using monoid: Monoid[W]): Writer[W, B] = Writer[W, B] { () => val (w1, a) = underlying.run() val (w2, b) = f(a).run() (monoid.combine(w1, w2), b) }
def unit[W, A](a: => A)(using monoid: Monoid[W]): Writer[W, A] = Writer[W, A](() => (monoid.empty, a))
Пример:
unit[String, Int](42).run()// res0: Tuple2[String, Int] = ("", 42)
Реализация
Реализация в Cats
import cats.data.Writerimport cats.instances.vector.*
val a = Writer(Vector( "It was the best of times", "it was the worst of times"), 1859)val (log, result) = a.run// val log: Vector[String] = Vector(It was the best of times, it was the worst of times)// val result: Int = 1859
Ссылки:
- Category Theory for Programmers - Bartosz Milewski:
- Cats
- Herding Cats
- Learning Scalaz
- Scala with Cats