Wilhelm
Wilhelm

Reputation: 33

Haskell - how to pattern match on backslash character?

I want to replace \n with a space in a String with a recursive function using pattern matching, but I can't figure out how to match the \ char.

This is my function:

replace :: String -> String
replace ('\\':'n':xs) = ' ' : replace xs
replace (x:xs) = x : replace xs
replace "" = ""

In ('\':'n':xs) the backslash would escape the single quote and mess up the code, so I wrote ('\\':'n':xs) expecting that the first \ would escape the escape of the second \ and would match a backslash in a String. However, it doesn't.

This is what happens when I try the function in GHCi:

*Example> replace "m\nop"
"m\nop"
*Example> replace "m\\nop"
"m op"

How can I match a single backslash?

Upvotes: 3

Views: 343

Answers (1)

Zeta
Zeta

Reputation: 105886

\n is a single character. If we use \n in a string like "Hello\nWorld!", then the resulting list looks like this: ['H','e','l','l','o','\n','W','o','r','l','d','!']. \n denotes a newline character, a single ASCII byte 10. However, since a newline isn't really easy to type in many programming languages, the escape sequence \n is used instead in string literals.

If you want to pattern match on a newline, you must use the whole escape sequence:

replace :: String -> String
replace ('\n':xs) = ' ' : replace xs
replace (x:xs)    = x   : replace xs
replace ""        = ""

Otherwise, you will only match the literal \.

Exercise: Now that replace works, try to use map instead of explicit recursion.

Upvotes: 5

Related Questions