Home > Net >  Haskell function incompatible type and definition
Haskell function incompatible type and definition

Time:06-11

I'm trying to understand this function (taken from here)

escape :: String -> String
escape =
  let
    escapeChar c =
      case c of
        '<' -> "&lt;"
        '>' -> "&gt;"
        _ -> [c]
  in
    concat . map escapeChar

My questions are:

  1. 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?
  2. What is the relationship between escapeChar and c? How is that relationship established? Does c coming right after escapeChar 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 '<' = "&lt;"
escapeChar '>' = "&gt;"
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 and c? How is that relationship established? Does c coming right after escapeChar have 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.

  • Related