Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell function incompatible type and definition

Tags:

haskell

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?
like image 731
ghg534 Avatar asked Mar 03 '26 18:03

ghg534


2 Answers

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)
like image 99
Iceland_jack Avatar answered Mar 05 '26 07:03

Iceland_jack


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.

like image 45
Willem Van Onsem Avatar answered Mar 05 '26 09:03

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!