Haskell函数类型和定义不兼容

fhg3lkii  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(161)

我正在尝试理解此函数(取自here

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

我的问题是:
1.根据类型,escape是一个接受String的函数。但是在函数定义中,它似乎没有接受任何参数。这是如何工作的?

  1. escapeCharc之间的关系是什么?这种关系是如何建立的?c紧跟在escapeChar之后是否有意义?
ppcbkaq5

ppcbkaq51#

如果escapeChar是使用模式匹配的顶级定义,会不会更容易一些:

escape :: String -> String
escape = concatMap escapeChar

escapeChar :: Char -> String
escapeChar '<' = "&lt;"
escapeChar '>' = "&gt;"
escapeChar ch  = [ch]

[ch]是一个单例列表,它将ch :: Char转换为[ch] :: String
在Haskell中,您可以从/向每边(eta conversion)移除/添加参数。escape是的 *eta约简 * 形式

escape :: String -> String
escape str = concatMap escapeChar str

就像,如果你想定义一个同义词(+),你有等价的写法。我觉得add = (+)是最清楚的,你是在标识两个函数。两边的参数是一样的,所以我们不指定它们。

add :: Int -> Int -> Int
add     = (+)
add a   = (+) a
add a   = (a +)
add a b = (+) a b
add a b = a + b

以下是escape的等效写法:
第一个

yduiuuwa

yduiuuwa2#

根据类型,escape是一个接受字符串的函数。但是在函数定义中,它似乎不接受任何参数。这是如何工作的?
concat . map escape返回一个 * 函数 *。该函数将接受一个字符串并对其进行处理。
escapeCharc之间的关系是什么?这种关系是如何建立的?c紧跟在escapeChar之后是否有意义?
是的,这是第一次(也是唯一的)参数。它是一个Char字符,并且escapeChar函数将该CharMap到String上。这会将给定String的每个CharMap到一个子字符串,然后将这些子字符串连接在一起。

sqxo8psd

sqxo8psd3#

map函数有一个签名(a -> b) -> ([a] -> [b]),这意味着map函数接受一个函数(escapeChar函数),并返回一个使用该函数转换列表的函数(escapeChar函数)。map escapeChar返回一个对字符串中的每个字符使用escapeChar函数转换字符串的函数。

相关问题