Reputation: 11
Doing exercises in Richard Bird's book "Introduction to Functional Programming Using Haskell," second edition. In the last line in the following code, I get the error:
"Parse error in pattern (n `times` Succ m)
Note that the same pattern (with m and n interchanged) was accepted in the definition of times
. Why am I getting this error?
data Nat = Zero | Succ Nat
deriving (Eq, Ord, Show)
plus :: Nat -> Nat -> Nat
m `plus` Zero = m
m `plus` Succ n = Succ (m `plus` n)
m `times` Zero = Zero
m `times` Succ n = (m `times` n) `plus` m
divide :: Nat -> Nat -> Nat
Zero `divide` m = Zero
(n `times` Succ m) `divide` n = Succ m
Upvotes: 1
Views: 298
Reputation: 183918
You get a parse error on
(n `times` Succ m) `divide` n = Succ m
because the arguments of the defined function must be patterns, that is
_
foo
F{field1 = value1, ..., fieldN = valueN}
(if the constructor F
is defined using named field syntax)1
, "foo"
-1
(1,2)
[1,2]
(pat)
, wher pat
is a pattern~pat
, where pat
is a patternand the first argument here is not a pattern but a function application of a non-constructor function.
A pattern allows to deconstruct a value, but an ordinary function application doesn't. For your problem, if you have
12 `divide` 4
-- and all that is available when the function is called is the value, not how it was obtained -- your attempted function definition would require that the compiler factors the value to check whether it can be written in the given form.
Another problem in that line is that you use the identifier n
twice, but any variable identifier can only appear once in a pattern-match.
Note that the same pattern (with
m
andn
interchanged) was accepted in the definition oftimes
.
In the definition
m `times` Succ n = (m `times` n) `plus` m
the function times
is defined for some kinds of arguments. The entire left hand side is not a pattern, there we have the two patterns m
- a variable pattern that matches every argument and binds it to the name m
- and Succ n
(that contains the nested variable pattern n
).
The left hand side of the definition consists of the defined name (times
) and two patterns for the arguments.
In the definition of divide
, the same structure is expected, the name to be defined, and two patterns for the arguments.
(n `times` Succ m) `divide` n = Succ m
So when the parser encounters the opening parenthesis, it expects a parenthesised pattern. But it finds
n `times` Succ m
pattern infix-function-application pattern
The top node of the expression tree of that is times
, which is not a constructor. Hence the part between the parentheses cannot be parsed as a pattern.
Upvotes: 3