I am trying to write a reverse Polish notation evaluator using foldr and this is what I have so far :
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 []
I have tried to resolve the error by swapping the positions of this : (x * y):ys and this (x:y:ys) but I keep getting this error:
Rpn.hs:14:7: error: Parse error in pattern: x * y
|
14 | step (x * y):ys "*" = (x:y:ys)
| ^^^^^
Failed, no modules loaded.
any help would be appreciated on how to resolve this. Thank you
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
Try saying
step (x:y:ys) "*" = (x * y) : ys
The same for the other operators. The last line of step
looks OK.
There are some problems here. The first one is that you swap "input" and "output" in your step
function. Indeed if you encounter a multiplication ( "*"
) you pop two items from the stack, and push the result of the multiplication on the stack. The step
function should thus look like:
step :: [Int] -> String -> [Int]
step "*" =
step "+" =
step "-" =
step xs numberString = read numberString:xs
The parenthesis for the (x:y:ys)
are necessary here, since we use the same parameter: a list of Int
s.
Furtermore you can not write foldr step []
and expect that it will yield an Int
. The foldr
will return the accumulator, and that is a list of Int
s, hence foldr step [] somelist :: [Int]
. You can use for example head
to obtain the first element.
The type of the accumulator and the element should be swapped, we can make use of flip :: (a -> b -> c) -> b -> a -> c
to flip the two parameters.
Finally you should reverse the list of strings, not the output, thus the function should look like:
rpnRec :: [String] -> Int
rpnRec = . foldr ( step) [] .
where safeHead [] = 1
safeHead (x:_) = x
For example:
Prelude> rpnRec ["2", "3", "*", "5", "+"]
11
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.