2

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.

Eben Kadile
  • 759
  • 4
  • 21

2 Answers2

6

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: '\\'.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
2

The backslash is the escape character so it needs to be doubled up to represent a single backslash: '\\'.

processInput ('\\':input) = processLambda input
...

-- or...
processInput input
    | head input == '\\'                      = processLambda (tail input)
...
Chad Gilbert
  • 36,115
  • 4
  • 89
  • 97