簡體   English   中英

Haskell 使用 foldr 實現 rpn

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM