Reputation: 77
Can someone please tell me what is wrong here? I can't figure out where the error is. I'm new to haskell, so I don't know every rule of syntax atm.
parseS (s:xs) | all isDigit s = (xs, Lit (read s))
| s == " " = parseS xs
| s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e)
| s == "+" = (xs'', Sum e e') where
(xs', e) = parseS xs
(xs'', e') = parseS xs'
| s == "*" = (xs'', Mul e e') where <- parse error on input on this line
(xs', e) = parseS xs
(xs'', e') = parseS xs'
Upvotes: 2
Views: 118
Reputation: 85887
This is how Haskell sees your code:
parseS (s:xs)
| all isDigit s = (xs, Lit (read s))
| s == " " = parseS xs
| s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e)
| s == "+" = (xs'', Sum e e')
where
(xs', e) = parseS xs
(xs'', e') = parseS xs'
| s == "*" = (xs'', Mul e e')
where
(xs', e) = parseS xs
(xs'', e') = parseS xs'
A where
block attaches to a declaration, which in your case is the whole parseS
definition.
The next line starting with |
is seen as the start of a new declaration, which is invalid because you can't start a declaration with |
.
The easiest fix is to stop using where
for local bindings and use let
instead, like this:
| s == "+" =
let
(xs', e) = parseS xs
(xs'', e') = parseS xs'
in
(xs'', Sum e e')
| s == "*" =
let
(xs', e) = parseS xs
(xs'', e') = parseS xs'
in
(xs'', Mul e e')
Upvotes: 2
Reputation: 89123
The problem is that the first where
clause is taken as the end of the definition for parseS (s:xs)
. You're trying to add another guarded case afterwards, but the parser doesn't see it as attached to the same definition.
There's several ways you could fix this.
You could fix this by using a let ... in
instead for s == "+"
| s == "+" = let (xs', e) = parseS xs
(xs'', e') = parseS xs
in (xs'', Sum e e')
| s == "*" = (xs'', Mul e e') where
(xs', e) = parseS xs
(xs'', e') = parseS xs'
But there's an easier way to do it - just drop that where
clause.
| s == "+" = (xs'', Sum e e')
| s == "*" = (xs'', Mul e e') where
(xs', e) = parseS xs
(xs'', e') = parseS xs'
The variables defined in a where
clause are in scope for the entirety of a definition (for all guard cases), so your definition of xs''
can be reused for both cases.
Upvotes: 3