gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 13:38:22 25 4
gpt4 key购买 nike

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

  • 保留参照透明性
  • 保持功能纯净
  • update函数转换数据结构状态。由于破坏性更新位于此函数内,并且无法从外部获取数据结构的句柄,因此我认为此函数是纯函数且具有参照透明性。
    def update(i : Int,d : Double) = State[ArraySeq[Double], Unit]{
    case xs: ArraySeq[Double] => {xs(i) = d; (xs, ())}
    }
    app函数是一个玩具函数,它将使用一系列 double并修改其状态:
    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的 STArray。这是解决此问题的一个非常聪明的解决方案,在像Haskell这样的语言中,这是一种很有意义的方法。我自己的感觉是,这在Scala中几乎总是错误的解决方案。如果您确实需要可变数组的性能,请使用本地可变数组,并确保不要将其泄漏给外界。如果您不需要那种性能(大多数时候不需要),请使用 State之类的东西。

    关于scala - 纯度,参照透明性和状态单价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30585224/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com