加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

什么时候在Scala中使用ST monad?

发布时间:2020-12-16 19:16:14 所属栏目:安全 来源:网络整理
导读:Scalaz提供了对有状态计算的很好的抽象:ST monad. ST monad允许以功能形式捕获副作用计算. 在Haskell中,我想,使用这样的monad是有效实现某些命令式算法的唯一方法. 但是在Scala中,如果需要,我可以简单地使用可变数据结构. 我发现,使用Scalaz的功能概念带来
Scalaz提供了对有状态计算的很好的抽象:ST monad.

ST monad允许以功能形式捕获副作用计算.

在Haskell中,我想,使用这样的monad是有效实现某些命令式算法的唯一方法.

但是在Scala中,如果需要,我可以简单地使用可变数据结构.

我发现,使用Scalaz的功能概念带来了计算开销.参见例如this question.因此,如果期望的目标是效率的提高,则从功能实现切换到使用ST monad的功能实现似乎是不合理的.

我问的是:

>什么时候使用ST monad是合理的?
>你在哪些情况下使用它,它似乎是一个不错的选择?

解决方法

正如唐斯图尔特正确指出的那样,你似乎在寻找ST monad而不是州monad.所以我的答案就是这个.

ST monad用于允许Haskell中的局部可变性,其中通常不允许可变性.例如,如果要编写命令求和函数,则可以使用ST monad.使用scalaz的这种函数的一个例子是(取自here):

def sumST[S,A](as: List[A])(implicit A: Numeric[A]): ST[S,A] =
  for { n <- newVar(A.zero)
        _ <- as.traverseU(a => n.mod(A.plus(_,a)))
        m <- n.read } yield m

def sum[A : Numeric](as: List[A]): A =
  runST(new Forall[({type λ[S] = ST[S,A]})#λ] {
    def apply[S] = sumST[S,A](as)
  })

显然在scala我们也可以写:

def sum[A](xs: List[A])(implicit N: Numeric[A]) = {
  var sum = N.zero
  val it = xs.iterator
  while (it.hasNext) {
    sum = N.plus(sum,it.next)
  }
  sum
}

这仍然是引用透明的,因为没有可变状态逃避函数的范围.在Haskell中,它用于这些情况,因为我们根本就没有var.

那么我们为什么要在scala中使用ST呢?如果你想处理一个可变结构(比如一个数组)并想要保证,这个可变结构不会逃避计算的范围,但必须首先变成一个不可变的结构,你可以使用ST.在scalaz中,你有STArray这样的情况,当ST monad运行时,它将变成一个ImmutableArray.一个很好的例子是binary sort example in scalaz.值得一读的是RúnarBjarnason的blog article on ST monad.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读