2007-09-23

Haskell で状態更新ループ

parsec で式のリストを作り,それを先頭から順に読んで状態を更新していくループを実装してみる.

仕様: 空白を含む数字の列を1桁の数列とみなし,それを順に足しあげていく.加算の結果を状態とする.

まず1桁の数字を読んで文字として返すパーザ:

digit_ws = do d <- digit
              skipMany space
              return d

数値の列を返すパーザ:

digits = do cs <- many1 digit_ws
            return $ map (read . (: [])) cs

read . (: []) は数字文字1個を数値に変換する関数(ちょっと不自然...).

このパーザでパーズする関数:

p cs = case parse digits "" cs of
       Left err  -> []
       Right val -> val

まず単純に使ってみる.

main = do cs <- getContents
          print $ p cs

これを実行すると

$ echo "12345" | runghc digits.hs
[1,2,3,4,5]

となる.

足しあげてみよう.

seqsum ior []  =    return ()
seqsum ior lst = do modifyIORef ior (+ (head lst))
                    readIORef ior >>= print
                    seqsum ior (tail lst)

main は次のようになる.

main = do cs <- getContents
          ior <- newIORef 0
          seqsum ior (p cs)
          readIORef ior >>= print

$ echo "12345" | runghc digits.hs
1
3
6
10
15
15

0 件のコメント:

コメントを投稿