2013-08-15 2 views
7

スカルズのSTでちょっと遊んでいたところで、トラバースタイプの内容を使ってSTRefを修正したかったのです。 Haskellでは、私は次のように(Haskellのウィキから取られた)ことを行うことができます:スララズforM_

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

    n <- newSTRef 0 

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

    readSTRef n 

は、残念ながら私はscalazでforM_のための同等のものを見つけることができませんでした。だから質問は、どうすればスカラーズでこれをすることができますか?

答えて

6

ご存知のように、forM_mapM_の反転版です。

あなたはmapMmapM_の一般化バージョンとして、(はScalazでを実装している)traversetraverse_を使用することができます。

Data.TraversablemapMの独自の実装をtraverseという形でエクスポートします。

sumSTのscalazバージョンは次のようになります。それはそんなに多く冗長Haskellのバージョンよりも、なぜ疑問に思う読者のために

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

:私たちは、ランク2多相型を表すためにForall形質を使用する必要があります。 Scalaで完全な説明については、http://apocalisp.wordpress.com/2011/03/20/towards-an-effect-system-in-scala-part-1/を参照してください。

+0

完璧、ありがとうございます! – drexin

関連する問題