takkan_mのHaskell再挑戦 RSSフィード

2007-03-02

逆ポーランド記法 01:13 逆ポーランド記法 - takkan_mのHaskell再挑戦 を含むブックマーク はてなブックマーク - 逆ポーランド記法 - takkan_mのHaskell再挑戦 逆ポーランド記法 - takkan_mのHaskell再挑戦 のブックマークコメント

はてなダイアリーで書いている方の日記最近カロリー計算(ただ数字をたしているだけ)のためにてきとうなプログラムを書くというのをしているのですが、5日目にしてネタにつきたので、逆ポーランド記法の計算機をつくりました。

haskell taka$ cat rPo.hs 
rPo :: String -> Integer
rPo str = evalPo [] $ words str
    where
        evalPo :: [Integer] -> [String] -> Integer
        evalPo l []     = head l
        evalPo l (x:xs) = if elem x exprs
                            then flip evalPo xs $ flip  evalExpr l $  getExpr x 
                            else flip evalPo xs $ flip (:) l $ strToInteger x
        exprs = [ "+" , "-" , "*" , "/" ]
        getExpr :: String -> ( Integer  -> Integer -> Integer)
        getExpr x
            | x == "+" = (+)
            | x == "-" = (-)
            | x == "*" = (*)
--          | x == "/" = (/)
        strToInteger = (read :: String -> Integer)
        evalExpr :: (Integer -> Integer -> Integer) -> [Integer] -> [Integer]
        evalExpr ex (x:y:xs) = flip (:) xs $ ex y x

testData = [ ( rPo , "390 1042 + 191 204 + +" , 1827) ,
             ( rPo , "365 328 + 210 + 191 + 577 90 + +" , 1761),
             ( rPo , "380 432 165 60 135 292 80 + + + + + +", 1544),
             ( rPo , "288 857 37 + + 185 + 204 + 85 +" , 1656),
             ( rPo , " 3 2 + 4 * 4 -" , 16)]

testEql :: (Eq b) => [ ( ( a -> b) , a , b) ] -> [ (Bool,b,b) ]
testEql = map (\(x,y,z) -> ((z ==( x y)) , (x y) , z))

文字列から数値の変換がわからなかったので趣味的にっきさんからstrToIntegerは拝借させていただきました。readでやるのね。

(/)をコメントアウトしているのは、(/)の型をまちがえてIntegerでつくってしまったため。ちょっと睡魔が襲ってきているので、起きたら対応するかも。

で、testEqlというテスト関数を作ってみた。関数とその引数期待値のタプルを要素とした配列をもらい、その比較結果と値のタプル配列を返す。全部Trueなら成功。

実行結果はこちら

*Main> testEql testData
[(True,1827,1827),(True,1761,1761),(True,1544,1544),(True,1656,1656),(True,16,16)]

最初は、最後のデータでFalseになった。理由はevalExprを

evalExpr ex (x:y:xs) = flip (:) xs $ ex x y

としてしまい、(False,-16,16)だって。スタックから数値を取り出して適用する順序を間違ってしまいました。

もっと、すっきり書けないかなぁ。

KarimeKarime2012/05/05 10:44That's a smart answer to a tricky qstueion

RameshRamesh2013/07/27 11:04A simple and innlielgett point, well made. Thanks!

TolgaTolga2013/07/29 19:34It's a pleasure to find such raaiontlity in an answer. Welcome to the debate.

VebyVeby2013/07/30 11:23As Charlie Sheen says, this article is <a href="http://wwceiyjpsq.com">"WNI!INGN"</a>

AlmogAlmog2013/07/31 04:29Awesome you should think of sotnhmieg like that http://pzlmmii.com [url=http://sabwatj.com]sabwatj[/url] [link=http://jdcivzkkvm.com]jdcivzkkvm[/link]

LisaLisa2013/07/31 13:16<a href=\"http://qicnzp.com\">Kngldewoe</a> wants to be free, just like these articles!

AbidAbid2013/07/31 18:55If you're reading this, you're all set, padrren! http://djytknvavcd.com [url=http://abirktt.com]abirktt[/url] [link=http://qcqxweqocp.com]qcqxweqocp[/link]