纯度,参照透明性和状态单价

MK

我目前正在设计一种数值算法,作为其运算的一部分,它需要doubles多次更新向量由于该算法必须尽可能地节省空间和时间,因此,我不想对传统类型的FP代码进行编码,这种FP代码在每次对其进行操作后都会在后台创建许多版本的数据结构。我也不想创建可变的数据结构并使它们全局可用。因此,我决定使用可变数据结构,但随后选择在Statemonad中进行可变操作由于这是我第一次使用Statemonad,因此我想确认是否有

  1. 保留参照透明性
  2. 保持功能纯度

update函数转换数据结构状态。由于破坏性更新位于该函数内,并且无法从外部获取数据结构的句柄,因此我认为此函数是纯函数且具有参照透明性。

def update(i : Int,d : Double) = State[ArraySeq[Double], Unit]{
  case xs: ArraySeq[Double] => {xs(i) = d; (xs, ())}
}

app函数是一个玩具函数,它将消耗doubles序列并修改其状态:

def app : State[ArraySeq[Double], Unit] = for{
    _ <- update(0, 3.142)
  // do a heap of stuff on ArraySeq
}yield()

称呼:

app(Vector(0.0, 1.0, 2.0, 3.0, 4.0).to[ArraySeq])._1.to[Vector]

结果:

res0: Vector[Double] = Vector(3.142, 1.0, 2.0, 3.0, 4.0)
特拉维斯·布朗

我猜您可以说您update自己是纯洁的,就其本身而言,它仅表示某种变异,但是一旦您运行它,所有的赌注都将关闭:

scala> val xs = List(1.0, 2.0, 3.0).to[ArraySeq]
xs: scala.collection.mutable.ArraySeq[Double] = ArraySeq(1.0, 2.0, 3.0)

scala> update(0, 10).eval(xs)
res0: scalaz.Id.Id[Unit] = ()

scala> xs
res1: scala.collection.mutable.ArraySeq[Double] = ArraySeq(10.0, 2.0, 3.0)

这是一个糟糕的场景,与纯透明或参照透明相反。

State在您的示例中并没有真正为您买任何东西-您app以这样的方式打电话,使您拥有ArraySeq别人无法变异的事实您不妨硬着头皮,以一种通常的方式在您控制的范围内使用可变数据结构,即,编写app如下:

def app(xs: Vector[Double]): Vector[Double] = {
  val arr = xs.to[ArraySeq]
  // Perform all your updates in the usual way
  arr.toVector
}

这实际上纯净的,并且是参照透明的,但是比State版本更诚实如果我看到类型的值State[Foo, Unit],我的假设将是这个值表示某种运算,其改变Foo成一个新的Foo变异原Foo这就是monad的全部状态-它提供了一种对不可变数据结构进行操作建模的好方法,并以一种看起来像变异的方式来构成它们。如果将它与实际的变异混合在一起,则可能会使使用您的代码的人感到困惑。

如果您真的想同时获得真正的突变和纯度,可以查看Scalaz's STArray这是解决此问题的一个非常聪明的解决方案,在Haskell这样的语言中,这是一种很有意义的方法。我自己的感觉是,这在Scala中几乎总是错误的解决方案。如果您确实需要可变数组的性能,则只需使用本地可变数组,并确保不要将其泄漏给外界。如果您不需要那种性能(大多数时候不需要),请使用State

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

组件,隔离功能和“参照透明性”

来自分类Dev

例外情况和参照透明性

来自分类Dev

当Java8使用参照透明性时

来自分类Dev

类型推断会干扰参照透明性

来自分类Dev

Skrollr背景透明性?

来自分类Dev

OpenGL透明性不透明

来自分类Dev

javascript 函数是否具有可变状态的引用透明性?

来自分类Dev

如何保证F#应用程序中的参照透明性?

来自分类Dev

OpenGL透明性无法正常工作

来自分类Dev

如何超越CSS的透明性方面

来自分类Dev

Gnome终端的背景透明性

来自分类Dev

定义参考透明性和确定性功能之间有什么区别?

来自分类Dev

为引导程序导航栏和照片增加半透明性,并增加字体大小

来自分类Dev

为什么Matlab的透明违反了透明性?

来自分类Dev

为什么材质设计中的活动图标和非活动图标具有不同的不透明性?

来自分类Dev

Firefox上具有不透明性和z-index的意外CSS 3过渡

来自分类Dev

我对可变类的“引用透明性”的理解正确吗?

来自分类Dev

酒吧半透明性在iOS 7.0.3中消失了

来自分类Dev

来自FillRectangle的不希望有的透明性

来自分类Dev

证书透明性快速入门:如何监视域列表?

来自分类Dev

如何为KDE的终端配置背景透明性?

来自分类Dev

GraphicsMagic无法识别PDF的背景透明性

来自分类Dev

如何改变图像的不透明性

来自分类Dev

Matplotlib pgf后端是否支持透明性?

来自分类Dev

使用图像透明性使黑色显示为“东西”

来自分类Dev

如何为KDE的终端配置背景透明性?

来自分类Dev

WPF PngBitmapEncoder:如何禁用背景透明性?

来自分类Dev

证书透明性快速入门:如何监视域列表?

来自分类Dev

jQuery不透明性慢褪色

Related 相关文章

热门标签

归档