在 Scala 中迭代列表的拉链 [英] Zipper to iterate over list in Scala

查看:50
本文介绍了在 Scala 中迭代列表的拉链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我之前的的后续问题.我可以使用迭代器、foldzipforeach 等来迭代 Scala 中的列表.现在我想知道是否存在 Zipper 最合适的用例.假设我需要没有并发的只读访问.

This is a follow-up to my previous question. I can use an iterator, fold, zip, foreach and others to iterate over a list in Scala. Now I wonder if there are use cases where Zipper is most appropriate. Suppose I need read-only access without concurrency.

你能举出这样的例子并解释为什么 Zipper 是最好的选择吗?

Could you give such an example and explain why the Zipper is the best choice?

推荐答案

关于 zippers 的许多巧妙之处之一是它们有一个 comonad 实例,它允许我们非常优雅地解决某一类问题.

One of the many neat things about zippers is that they have a comonad instance, which allows us to solve a certain class of problems very elegantly.

这是我脑海中的一个简单例子.假设我们有一个数字序列,我们想用指数移动平均值做一个简单的平滑形式,其中列表中每个位置的新值是当前值和所有其他值的平均值,但是距离越远的邻居贡献越少.

Here's a quick example off the top of my head. Suppose that we've got a sequence of numbers and we want to do a simple form of smoothing with an exponential moving average, where the new value for each position in the list is an average of the current value and all the other values, but with more distant neighbors contributing less.

命令式计算这不是一件非常困难的事情,但如果我们使用拉链和共联组合,它离单行也不会太远:

This isn't a terribly hard thing to compute imperatively, but if we use a zipper and a comonadic cobind it's not too far from a 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
}

现在如果我们写:

val result = smooth(NonEmptyList[Double](0, 0, 0, 1, 0, 0, 0)).toList

我们将得到以下等价物:

We'll get the moral equivalent of:

List(1 / 24, 1 / 12, 1 / 6, 1 / 3, 1 / 6, 1 / 12, 1 / 24)

考虑到我们如何定义问题,这就是我们想要的.

Which is what we want, given how we defined the problem.

这篇关于在 Scala 中迭代列表的拉链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆