I'm trying to define xor
using pattern matching in Haskell by:
(xor) :: Bool -> Bool -> Bool
True xor False = True
False xor True = True
True xor True = False
False xor False = False
However this gives the error:
Invalid type signature: (xor) :: Bool -> Bool -> Bool
Should be of form <variable> :: <type>
I'm confused as to why this error is being thrown. Also if I replace xor
with something such as &&
the script loads fine.
Haskell differentiates between identifiers and operator symbols. Identifiers are alphanumeric plus '
, and are valid terms on their own; if an identifier prefix
has a function type, you can thus call it as prefix arg1 arg2
. Operator names are sequences of symbols, and are called as arg1 !&$ arg2
.1 But sometimes, you want to use identifiers as infix operators or treat an infix operator as an identifier. Thus, if you surround any prefix function name with `
s, it becomes an operator and you can (must) use it as infix: arg1 `prefixFunc` arg2
. And contrariwise, if you wrap an infix operator name in parentheses, it becomes syntactically valid on its own, and so can be called in prefix form: (!&$) arg1 arg2
.2
When declaring a type signature for a variable, you need to give the variable's name as an identifier.3 For an ordinary function name like xor
, that's just the name; for an operator like &&
, you wrap it in parentheses, as discussed above, which is why you write (&&) :: Bool -> Bool -> Bool
. Thus, you'd write
xor :: Bool -> Bool -> Bool
True `xor` False = True
False `xor` True = True
True `xor` True = False
False `xor` False = False
Note that I had to make two changes. If you left off the backticks in the definition lines, it'll be as though you were trying to do pattern matching: True
would look like a constructor which took two arguments, and xor
would be the first one.4
(Also, just for kicks, a shorter definition: xor = (/=)
:-))
1 The lexical structure is in §2.4
2 The expression structure is in §3.2.
3 The structure of type signatures is in §4.4.1, referring to the definition of var in §3.2.
4 The structure of bindings is in §4.4.3.