Scalaz相当于forM_

dre*_*xin 7 functional-programming scala scalaz

我只是ST在scalaz中玩了一下并且到了关键点,在那里我想使用可遍历类型的内容来修改我的内容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
Run Code Online (Sandbox Code Playgroud)

不幸的是,我无法找到forM_scalaz中的等价物.所以问题是,我怎么能用scalaz做到这一点?

Ben*_*mes 6

你可能知道,forM_是翻版的mapM_.

你可以用traversetraverse_(这在Scalaz实现),作为广义版本mapMmapM_.

作为证据,看出Data.Traversable出口自己的实现mapM,就此而言traverse.

scalaz版本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)
  })
Run Code Online (Sandbox Code Playgroud)

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