【问题标题】:Scalaz equivalent to forM_Scalaz 等价于 forM_
【发布时间】:2013-08-15 14:58:43
【问题描述】:

我只是在 scalaz 中使用 ST 玩了一下,然后我想使用可遍历类型的内容来修改我的 STRef。在 Haskell 中,我可以这样做(取自 Haskell wiki):

sumST :: Num a => [a] -> a
sumST xs = runST $ do

   n <- newSTRef 0

    forM_ xs $ \x -> do
        modifySTRef n (+x)

   readSTRef n

不幸的是,我无法在 scalaz 中找到 forM_ 的等价物。所以问题是,我怎样才能用 scalaz 做到这一点?

【问题讨论】:

    标签: scala functional-programming scalaz


    【解决方案1】:

    您可能知道,forM_mapM_ 的翻转版本。

    您可以使用traversetraverse_(在Scalaz 中实现),作为mapMmapM_ 的通用版本。

    作为证据,看到Data.Traversable 导出了它自己的mapM 实现,就traverse 而言。

    sumST 的 scalaz 版本可能如下所示:

    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)
      })
    

    对于想知道为什么它比 haskell 版本更冗长的读者:我们必须使用 Forall 特征来表示 Scala 中的 rank-2 多态类型。请参阅http://apocalisp.wordpress.com/2011/03/20/towards-an-effect-system-in-scala-part-1/ 以获得更完整的解释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2013-08-08
      相关资源
      最近更新 更多