我想在Haskell中實現一個RPN caculator。這是來自Learn You a Haskell的練習。 這裏是我的代碼:在一個RPN caculator實現中的Haskell問題
import Data.List
solveRPN :: String -> Int
solveRPN str = head $ foldl putStack [] (words str)
where putStack accumulator token
| token == "+" = pFunction (+)
| token == "-" = pFunction (-)
| token == "*" = pFunction (*)
| token == "/" = pFunction (`div`)
| otherwise = accumulator ++ [read token :: Float]
where pFunction function = (int $ init accumulator) ++ [function argu1 argu2]
argu1 = last accumulator
argu2 = last $ init accumulator
功能solveRPN
第一分割字符串爲標記。 (例如:"4 3 2 + *"
→["4","3","2","+","*"]
) 然後,將一個一個的令牌推入堆棧。如果它遇到一個操作員,堆棧中的最後兩個項目由操作員處理,然後將生成的值放回堆棧。當遍歷整個列表時,堆棧中只剩下一個項目,這就是答案。
這裏有一些問題:
在
(int $ init accumulator)
我想取消在堆棧中的最後兩個元素。有沒有其他替代(int $ init accumulator)
?該代碼無法通過編譯。 GHC說:「輸入解析錯誤(」
在這一行:| token == "/" = pFunction (
div)
。我懷疑問題可能來自pFunction
。它的參數是一個運算符(或者我可以稱它爲函數?),我不知道是否。?「函數作爲函數的參數」,在Haskell是法律這是法律是否有任何替代我的確在GHCI一些實驗,發現一些奇怪的事情:
Prelude> let plus = (+) Prelude> :t (+) (+) :: Num a => a -> a -> a Prelude> :t plus plus :: Integer -> Integer -> Integer
加號的類型與(+)的類型有什麼不同?
感謝您的關注和耐心。 (:
您一直在堆棧上使用必須遍歷整個堆棧的操作。你有沒有考慮倒轉你的堆棧? 'init'變成'tail','last'變成'head','stack ++ [x]'變成'x:stack',所以大部分堆棧操作變成O(1)。我想你不太關心表現,但這是值得思考的。 – user2407038
是的,這是一個好主意。實際上,Learn You a Haskell提供的答案使用您所描述的堆棧。 –