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做到这一点?
你可能知道,forM_是翻版的mapM_.
你可以用traverse与traverse_(这是在Scalaz实现),作为广义版本mapM和mapM_.
作为证据,看出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/.
| 归档时间: |
|
| 查看次数: |
278 次 |
| 最近记录: |