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,
escape
is 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
escapeChar
andc
? How is that relationship established? Doesc
coming right afterescapeChar
have 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
escapeChar
andc
? How is that relationship established? Doesc
coming right afterescapeChar
have a meaning?
Yes, it is the first (and only) parameter of the function. It is a Char
acter, 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.