7

我只是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

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

4

1 回答 1

6

您可能知道,forM_它是mapM_.

您可以使用traverseand traverse_(在 ScalazmapM实现)作为and的通用版本mapM_

作为证明,请参阅Data.Traversableexport 其自己的实现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)
  })

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

于 2013-08-15T15:05:37.410 回答