Pattern match is redundant
When declaring functions, the argument variables are new names. Your quote and doubleQuote are shadowing the functions rather than invoking the functions for pattern matching. In this way the language of pattern matching subtly deviates from the language of right-hand-sided expressions. To achieve what you want, either do
isBorder :: Char -> Bool
isBorder '\'' = True
isBorder '\"' = True
isBorder _ = False
or
isBorder :: Char -> Bool
isBorder c | quote == c = True
isBorder c | doubleQuote == c = True
isBorder _ = False
The philosophy is to first bind the argument to name and then to use a guard to invoke an expression that evaluates to a boolean.
The pattern can only be matched against concrete values, not against identifiers.
So the compiler essentially sees:
isBorder x = True
isBorder x = True
since quote
and doublequote
aren't the defined identifers but the names of the parameters.