Reputation: 325
When I try to compile the following code:
matcHelp :: String -> Stack Char -> Stack Char
matcHelp b = mtHelp b (MakeS([])) (MakeS([])) where
mtHelp b result1 result2 =
if (b == [])
then result1 result2
else if head b == '('
then mtHelp (tail b) (push '(' result1) (result2)
else if head b == '['
then mtHelp (tail b) (result1) (push '[' result2)
else if (head b == ')')
then mtHelp (tail b) (popOut result1) (result2)
else if (head b == ']')
then mtHelp (tail b) (result1) (popOut result2)
else mtHelp (tail b) (result1) (result2)
I get that the function push:
push :: a -> Stack a -> Stack a
push x (MakeS(xs)) = MakeS(x:xs)
is applied to too many arguments, specifically in the instance (push '(' result1)
. I don't see why?
The actual error I'm getting is:
Couldn't match expected type `t1 -> t0' with actual type `Stack a0'
In the return type of a call of `push'
Probable cause: `push' is applied to too many arguments
In the second argument of `mtHelp', namely `(push '(' result1)'
In the expression: mtHelp (tail b) (push '(' result1) (result2)
Failed, modules loaded: none.
Note: MakeS is a data constructor
newtype Stack a = MakeS([a]) deriving Show
Upvotes: 0
Views: 2811
Reputation: 6778
The issue is the line
if (b == []) then result1 result2
implies result1
is a function to be applied to result2
. From your type signature, matchHelp
is supposed to be returning a Stack Char
, so you've made an error here.
From your comments it's clear that you want to return multiple values from matchHelp
. In Haskell, all functions take one argument and return one result, always. Even a function like
(+) :: Int -> Int -> Int
takes one argument (an Int
) and returns one result (a function Int -> Int
). You could write the type signature like this:
(+) :: Int -> (Int -> Int)
but Haskell does this for you anyways. This is called "currying".
The Haskell way to return multiple values is to return a single tuple containing those values or a data structure that you've defined yourself.
Unrelated, your function is not very "Haskell-y" with all those if .. then .. else
and head/tail
when pattern matching and guards should be used instead. Here's the rewritten function with multiple return values in a tuple.
matchHelp :: String -> Stack Char -> (Stack Char, Stack Char)
matchHelp b = mtHelp b (MakeS []) (MakeS [])
where mtHelp [] result1 result2 = (result1, result2)
mtHelp (x:xs) result1 result2
| x == '(' = mtHelp xs (push '(' result1) (result2)
| x == '[' = mtHelp xs (result1) (push '[' result2)
| x == ')' = mtHelp xs (popOut result1) (result2)
| x == ']' = mtHelp xs (result1) (popOut result2)
| otherwise = mtHelp xs result1 result2
Upvotes: 5