Scalaz相当于forM_

时间:2013-08-15 14:58:44

标签: scala functional-programming scalaz

我只是在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做到这一点?

1 个答案:

答案 0 :(得分:6)

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

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

作为证据,请参阅Data.TraversablemapM为出口traverse导出其自己的sumST实施。

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) }) 的scalaz版本可能如下所示:

Forall

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