はじめに
いなたつアドカレの十四日目の記事です。
Haskellで逆ポーランド記法の計算機をつくってく記事の続きです
前回のぷよぐやむ
前回はcalc関数の足し算引き算の部分の計算を行う部分の実装を行いました。
calc :: String -> Double
calc = head . foldl folding [] . words
where folding (x:y:ys) "+" = (y + x):ys
folding (x:y:ys) "-" = (y - x):ys
これが前回のプログラムですね。これで、足し算引き算を畳み込みを行うことで実現していました。
しかしこれではまだプログラムは動作しないので、今回は動作させること、そして、掛け算割り算などの追加を行うことを目標にしていきます。
# じっそー
今は「+」と「-」しか処理ができないので、普通に数字がきた場合のパターンを作成しましょう
calc :: String -> Double
calc = head . foldl folding [] . words
where folding (x:y:ys) "+" = (y + x):ys
folding (x:y:ys) "-" = (y - x):ys
folding xs num = read num:xs
これで、最低限の動作が行えます。
main関数から特定の文字列でcalcを呼んでみましょう。
main = do
print $ calc "12 34 + 3 -"
$ runghc rpn_parser.hs
43.0
これを普通の数式にすると12 + 34 - 3
で43
になりますね。
戻り値はDouble型なので出力は43.0になりますね。
次はこれをコマンドライン引数に対応させていきます。
main :: IO ()
main = do
args <- getArgs
print $ calc $ args !! 0
入力した文字列を引数にcalcを実行します。
$ runghc rpn_parser.hs "12 34 + 15 -"
31.0
計算もちゃんとあっていますね。
最後に掛け算、割り算、累乗を実装します。
これは各演算子と同様に計算を行うだけですね
calc :: String -> Double
calc = head . foldl folding [] . words
where folding (x:y:ys) "+" = (y + x):ys
folding (x:y:ys) "-" = (y - x):ys
folding (x:y:ys) "*" = (y * x):ys
folding (x:y:ys) "/" = (y / x):ys
folding (x:y:ys) "**" = (y ** x):ys
folding xs num = read num:xs
これで、最低限動作する逆ポーランド記法の計算機が完成しました。
rpn_parser.hs
import System.Environment
calc :: String -> Double
calc = head . foldl folding [] . words
where folding (x:y:ys) "+" = (y + x):ys
folding (x:y:ys) "-" = (y - x):ys
folding (x:y:ys) "*" = (y * x):ys
folding (x:y:ys) "/" = (y / x):ys
folding (x:y:ys) "**" = (y ** x):ys
folding xs num = read num:xs
main :: IO ()
main = do
args <- getArgs
print $ calc $ args !! 0