[英]Haskell implementation of rpn using foldr
我正在嘗試使用 foldr 編寫一個反向波蘭符號評估器,這是我目前所擁有的:
step :: [Int] -> String -> [Int]
step (x * y):ys "*" = (x:y:ys)
step (x + y):ys "+" = (x:y:ys)
step (y - x):ys "-" = (x:y:ys)
step xs numberString = read numberString:xs
rpnRec ::[String] -> Int
rpnRec [] = 1
rpnRec = reverse .foldr step []
我試圖通過交換 this : (x * y):ys 和 this (x:y:ys) 的位置來解決錯誤,但我不斷收到此錯誤:
Rpn.hs:14:7: error: Parse error in pattern: x * y
|
14 | step (x * y):ys "*" = (x:y:ys)
| ^^^^^
Failed, no modules loaded.
任何有關如何解決此問題的幫助將不勝感激。 謝謝
step :: [Int] -> String -> [Int]
step (x * y):ys "*" = (x:y:ys)
step (x + y):ys "+" = (x:y:ys)
step (y - x):ys "-" = (x:y:ys)
step xs numberString = read numberString:xs
試着說
step (x:y:ys) "*" = (x * y) : ys
其他運營商也一樣。 step
的最后一行看起來沒問題。
這里有一些問題。 第一個是您在step
函數中交換“輸入”和“輸出”。 實際上,如果您遇到乘法 ( "*"
),您會從堆棧中彈出兩個項目,並將乘法的結果壓入堆棧。 因此, step
函數應如下所示:
step :: [Int] -> String -> [Int]
step (x:y:ys) "*" = x*y:ys
step (x:y:ys) "+" = x+y:ys
step (x:y:ys) "-" = x-y:ys
step xs numberString = read numberString:xs
(x:y:ys)
的括號在這里是必要的,因為我們使用相同的參數:一個Int
列表。
此外,您不能編寫foldr step []
並期望它會產生一個Int
。 foldr
將返回累加器,這是一個Int
列表,因此foldr step [] somelist :: [Int]
。 例如,您可以使用head
來獲取第一個元素。
累加器和元素的類型應該交換,我們可以使用flip :: (a -> b -> c) -> b -> a -> c
來翻轉兩個參數。
最后,您應該反轉字符串列表,而不是輸出,因此該函數應如下所示:
rpnRec :: [String] -> Int
rpnRec = safeHead . foldr (flip step) [] . reverse
where safeHead [] = 1
safeHead (x:_) = x
例如:
Prelude> rpnRec ["2", "3", "*", "5", "+"]
11
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.