I'm trying to understand this function (taken from here)
escape :: String -> String
escape =
let
escapeChar c =
case c of
'<' -> "<"
'>' -> ">"
_ -> [c]
in
concat . map escapeChar
My questions are:
- According to the type,
escapeis a function that takes aString. But it seems that in in the fuction definition it does not receive any argument. How does this work? - What is the relationship between
escapeCharandc? How is that relationship established? Doesccoming right afterescapeCharhave a meaning?
CodePudding user response:
Would it be easier if escapeChar were a top-level definition using pattern matching:
escape :: String -> String
escape = concatMap escapeChar
escapeChar :: Char -> String
escapeChar '<' = "<"
escapeChar '>' = ">"
escapeChar ch = [ch]
[ch] is a singleton list, it turns ch :: Char into a [ch] :: String.
In Haskell you can remove/add an argument from/to each side (eta conversion). escape is the eta reduced form of
escape :: String -> String
escape str = concatMap escapeChar str
Just like, if you wanted to define a synonym for ( ) you have equivalent ways of writing it. I feel like the add = ( ) is clearest, you are identifying the two functions. The arguments are the same on both sides so we don't specify them.
add :: Int -> Int -> Int
add = ( )
add a = ( ) a
add a = (a )
add a b = ( ) a b
add a b = a b
These are equivalent ways of writing escape:
escape = concat . map escapeChar
escape str = concat (map escapeChar str)
CodePudding user response:
According to the type, escape is a function that takes a String. But it seems that in in the fuction definition it does not receive any argument. How does this work?
concat . map escape returns a function. That function will take a string and process it.
What is the relationship between
escapeCharandc? How is that relationship established? Doesccoming right afterescapeCharhave a meaning?
Yes, it is the first (and only) parameter of the function. It is a Character, and the escapeChar function maps that Char on a String. The let clause thus defines a function escapeChar :: Char -> String that will then be used in concat . map escape (or perhaps better concatMap escape). This will map each Char of the given String to a substring, and these are then concatenated together as a result.
CodePudding user response:
the map function has a signature (a -> b) -> ([a] -> [b]) this means that the map function takes in a function(the escapeChar function) and returns a function that converts a list using that function(the escapeChar function). map escapeChar returns a function that converts a string using the escapeChar function on each character in the string.
