逆ポーランド記法計算機

Learn You a Haskell for Great Good!」の「Reverse Polish notation calculator」を計算途中の様子を表示するようにしてみました。

import Data.List
import Debug.Trace

solveRPN :: String -> Float 
solveRPN = head . foldl foldingFunction [] . words  
    where   foldingFunction stack "*"   = traceShow stack "*" (*)
            foldingFunction stack "+"   = traceShow stack "+" (+)
            foldingFunction stack "-"   = traceShow stack "-" (-)
            foldingFunction stack "/"   = traceShow stack "/" (/)
            foldingFunction stack "^"   = traceShow stack "^" (**)
            foldingFunction stack "ln"  = traceLog  stack
            foldingFunction stack "sum" = traceSum  stack
            foldingFunction stack str   = push stack str

            traceShow (x:y:ys) s exp = trace(show y ++" "++ s ++" "++ show x++"("++ show ys ++")") ((y `exp` x):ys)
            traceLog  (x:xs)         = trace("ln " ++ show x++"("++ show xs ++")") (log x:xs)
            traceSum   xs            = trace("sum " ++ show xs ) ([sum xs])
            push stack str           = trace(show (read str:stack))(read str:stack)

{-
> solveRPN "10 4 3 + 2 * -"  
[10.0]                 -- 10 をスタックに追加
[4.0,10.0]             -- 4 をスタックに追加
[3.0,4.0,10.0]         -- 3 をスタックに追加
4.0 + 3.0([10.0])      -- 3 と 4 を取り出し '+'してスタックに追加
[2.0,7.0,10.0]         -- 2 をスタックに追加
7.0 * 2.0([10.0])      -- 2 と 7 を取り出し '*'してスタックに追加
10.0 - 14.0([])
-4.0

> solveRPN "90 34 12 33 55 66 + * - + -" 
[90.0]
[34.0,90.0]
[12.0,34.0,90.0]
[33.0,12.0,34.0,90.0]
[55.0,33.0,12.0,34.0,90.0]
[66.0,55.0,33.0,12.0,34.0,90.0]
55.0 + 66.0([33.0,12.0,34.0,90.0])
33.0 * 121.0([12.0,34.0,90.0])
12.0 - 3993.0([34.0,90.0])
34.0 + -3981.0([90.0])
90.0 - -3947.0([])
4037.0

>  solveRPN "2.7 ln"
[2.7]
ln 2.7([])
0.9932518

> solveRPN "10 10 10 10 sum 4 /"  
[10.0]
[10.0,10.0]
[10.0,10.0,10.0]
[10.0,10.0,10.0,10.0]
sum [10.0,10.0,10.0,10.0]
[4.0,40.0]
40.0 / 4.0([])
10.0

> solveRPN "10 2 ^"  
[10.0]
[2.0,10.0]
10.0 ^ 2.0([])
100.0

-}