水曜日, 11月 05, 2008

Haskellを使ってみる (3)

ねこさんは数値データをテキストファイルでやり取りすることが多いのですが、Haskellでの実数データの読み込みは互換性の観点からすると都合がよろしくありません。read関数だけでなくParsecにもfloatというパーサが用意されているらしいのですが、これでは使い勝手が良くないのです。こちらにfloatパーサを使いつつ改善したパーサが紹介されていますが、Fortranの出力形式にも対応して欲しいねこさんには不満が残ります。

仕方が無いのでParsecの練習を兼ねて自前でパーサを組んでみることにしました。

realNum :: Parser Double realNum = do sign <- option 1 (do s <- oneOf "+-"                                   return \$ if s=='-' then -1 else 1)              int  <- option 0 cntNum              option '.' (char '.')              frac <- option 0 cntNum              exp  <- option 0 (do oneOf "eEdD"                                    e <- intNum                                   return \$ e)              return \$ (fromIntegral sign) *                         (fromIntegral int + toFrac (fromIntegral frac)) *                           (10**(fromIntegral exp))           where             toFrac n = if n<1 then n                        else toFrac \$ n/10 cntNum :: Parser Int cntNum = do n <- many1 digit             return \$ (read n :: Int) intNum :: Parser Int intNum = do sign <- option 1 (do s <- oneOf "+-"                                  return \$ if s=='-' then -1 else 1)             num   <- many digit             return \$ sign * (read num)

初めて書いた割には結構それなりに動いているようです。よかった。

話は変わりますが、代数的データ型を使ってコードを書いているとデバッグ時に「(Show ~)のインスタンスがないよー?」と怒られてちょっと悲しいのですが、これを解決するには当然(Show ~)のインスタンスを定義すればいいと。

data PointType = Point { x :: Double, y :: Double } instance Show PointType where     show (Point x y) = "Point " ++ (show x) ++ " " ++ (show y)

これでデバッグしやすくなりました。

ところで、Haskellにはsprintfに相当する関数はないのでしょうか?とりあえずは実数の出力形式を細かく指定できればねこさんには十分なのですが。

2 件のコメント:

匿名 さんのコメント...

Show については、
data Point = Point {x :: Double, y :: Double} deriving (Eq,Show)
とかやるとよいです。

printf は
http://www.haskell.org/ghc/dist/current/docs/libraries/base/Text-Printf.html
ってのがありますが、
http://www.haskell.org/ghc/dist/current/docs/libraries/base/Numeric.html
のほうがよいかも。

neko さんのコメント...

>匿名さん

このような僻地へお越しありがとうございますー。
めったに人が来ませんのでホントに嬉しいです。特にHaskellにお詳しい方ならなおさらです!

お返事はこちらのエントリーにも書かせて頂きました。↓
http://noranekosan.sakura.ne.jp/weblog/2008/11/haskell-4.html