Search code examples
haskelllambda-calculuslexical

How are apostrophes/character literals parsed in Haskell?


I'm trying to write something that reads Lambda expressions and outputs a beta reduced version. Lambdas will be typed as follows : \variable -> expression and applications will be of the form (expression) (expression). So if '\' is found at the beginning of the string it knows to process a Lambda and if '(' is found it knows to process an application.

I have a type for Lambda Expressions defined:

data Expression = Variable String
                | Lambda Expression Expression 
                | Apply Expression Expression 

Here's my first attempt at writing a function for reading the input

processInput :: String -> Expression
processInput ('\':input) = processLambda input
processInput ('(':input) = processApply input
processInput str         = Variable str

When I try to load this function I get

lexical error in string/character literal at ':'

So I tried using guards instead:

processInput input
    | head input == '\'                      = processLambda (tail input)
    | head input == '('                      = processApply (tail input)
    | otherwise                              = Variable input

But got

lexical error in string/character literal at character ' '

I have no idea what's wrong with either of these functions.


Solution

  • The backslash is a special character in string and character literals. You use to represent non-printable characters, line breaks and characters that would otherwise have special meaning in a literal. For example '\n' is a line break '\b' is a back space and '\'' is a single quote (without the \, the second ' would be seen as the end of the character literal).

    So when you write '\', the lexer sees the start of a character literal, followed by an escaped '. Now it expects another ' to close the character literal, but gets a colon instead, causing the error.

    To represent a backslash as a character literal, you escape the backslash with another backslash like this: '\\'.