Haskell新手对理解功能构成

时间:2014-05-06 22:30:21

标签: haskell

我一直在审查Haskell Hierarchical库中的这段代码片段。 我可以按照下面代码的大部分片段,但是“。” (函数组合)在这种情况下的行为抛出了我,因为我期望参数为foldr,特别是:foldr f z list。我将parseLine视为f,z视为M.empty,将行视为列表。所以我希望我的混淆是关于函数组合和where子句的行为。当我尝试从Haskell中理解时,任何理解这个函数的帮助都会非常受欢迎。

 -- Parse the file we've just read in, by converting it to a list of lines,
 -- then folding down this list, starting with an empty map and adding the
 -- username and password for each line at each stage.
  parseMap :: String -> PassDB
  parseMap = foldr parseLine M.empty . lines
     where parseLine ln map = 
             let [un, pw] = words ln
             in M.insert un pw map

2 个答案:

答案 0 :(得分:3)

您必须将此表达式解析为(foldr parseLine M.empty) . (lines)。因此,parseLineM.emptyfoldr的第一个和第二个参数,你是对的。但是,lines不是foldr的参数。

所以foldr仍然缺少一个参数,即foldr parseLine M.empty是类型[String] -> PassDB的函数。并且lines也缺少一个参数,它是来自String -> [String]的函数。这就是.在这里组成的两个功能。所以我们一起得到String -> PassDB类型的函数。

请注意,参数仍然缺失,因此parseMap是一个函数。正如它的类型注释所说的那样。

答案 1 :(得分:2)

首先我应该说,在Haskell中,所有函数都采用一个参数。这就是currying,这就是你发布的语法。

然后,此语法是pointfree样式的实例。您可以按照以下方式阅读它:

parseMap :: String -> PassDB
parseMap    s       = foldr parseLine M.empty . lines $ s
  where parseLine ln map = 
        let [un, pw] = words ln
        in M.insert un pw map

从上面的表单转到您发布的表单称为执行eta-reduction

当您可以执行eta-reduction时,可以通过将hlint(例如emacs与haskell-mode)集成的智能编辑器向您发出警告。

当你理解了这一切之后,理解函数组合只是意识到输入字符串将首先作为输入提供给lines,该函数将把字符串转换为列表,然后是结果列表将提供给foldr