Zipper to iterate over list in Scala -
this follow-up previous question. can use iterator, fold
, zip
, foreach
, others iterate on list in scala. wonder if there use cases zipper
appropriate. suppose need read-only access without concurrency.
could give such example , explain why zipper
best choice?
one of many neat things zippers have comonad instance, allows solve class of problems elegantly.
here's quick example off top of head. suppose we've got sequence of numbers , want simple form of smoothing exponential moving average, new value each position in list average of current value , other values, more distant neighbors contributing less.
this isn't terribly hard thing compute imperatively, if use zipper , comonadic cobind it's not far one-liner:
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 }
now if write:
val result = smooth(nonemptylist[double](0, 0, 0, 1, 0, 0, 0)).tolist
we'll moral equivalent of:
list(1 / 24, 1 / 12, 1 / 6, 1 / 3, 1 / 6, 1 / 12, 1 / 24)
which want, given how defined problem.
Comments
Post a Comment