Ответ 1
Одна из многих опрятных вещей о молниях - это то, что у них есть экземпляр comonad, который позволяет нам очень легко решить определенный класс проблем.
Вот пример из верхней части головы. Предположим, что у нас есть последовательность чисел, и мы хотим сделать простую форму сглаживания с экспоненциальной скользящей средней, где новое значение для каждой позиции в списке является средним значением текущего значения и всеми другими значениями, но с более отдаленными соседями, делающими меньше.
Это не ужасно сложно вычислить императивно, но если мы используем застежку-молнию и комонадическое cobind, это не слишком далеко от однострочного:
import scalaz._, Scalaz._
val weights = Stream.from(1).map(1.0 / math.pow(2, _))
def sumNeighborWeights(neighbors: Stream[Double]) =
neighbors.fzipWith(weights)(_ * _).sum
def smooth(data: NonEmptyList[Double]) = data.toZipper.cobind { z =>
(z.focus + sumNeighborWeights(z.lefts) + sumNeighborWeights(z.rights)) / 3
}
Теперь, если мы напишем:
val result = smooth(NonEmptyList[Double](0, 0, 0, 1, 0, 0, 0)).toList
Мы получим моральный эквивалент:
List(1 / 24, 1 / 12, 1 / 6, 1 / 3, 1 / 6, 1 / 12, 1 / 24)
Это то, что мы хотим, учитывая, как мы определили проблему.