【问题标题】:Haskell - Currying? Need further explanationHaskell - 柯里化?需要进一步解释
【发布时间】:2010-09-25 15:23:49
【问题描述】:

类似

addList :: [int] -> int
addList = foldl1 (+)

为什么会这样?咖喱部分。为什么没有变量?

【问题讨论】:

  • @Joren:实际上,通过高阶函数。 OP 询问了部分应用程序,现在询问了折叠;)@Matt:我见过的大多数体面的 Haskell 教程确实解释了这一点,尽管有时不是立即。如果您的根本无法解释,您可能想要切换。
  • 当你有模式匹配时我明白了。像 (((f 6) 7) 8) 返回 f 6,新参数为 7,然后为 8 做同样的事情。在这种情况下,说 addList [1,2,3,4] 返回,但我只是不知道如何fold1 得到那个列表。比如haskell是怎么知道的?我知道这与咖喱有关。
  • Sepp2k 的解释准确而简单。 haskell.org/haskellwiki/Currying有更正式的解释。
  • @delnan:好吧,马特问“为什么会这样”。我的猜测是“this”指的是“addList”,就像“为什么函数 addList 工作”一样。我同意将其解释为“为什么这个定义有效”更有意义。下一次,我只是要求澄清。

标签: haskell currying partial-application


【解决方案1】:

如果你定义像f x y = bla这样的函数,这与f x = \y -> bla相同,与f = \x -> (\y -> bla)相同。换句话说,f 是一个函数,它接受一个参数 x,并返回另一个接受一个参数 y 的函数,然后返回实际结果。这称为柯里化。

类似地,当您执行f x y 时,它与(f x) y 相同。 IE。您正在使用参数x 调用函数f。这将返回另一个函数,您将其应用于参数y

换句话说,当您执行addList xs = foldl1 (+) xs 时,您首先调用foldl1 (+),然后返回另一个函数,您将其应用于xs。所以由于foldl1 (+)返回的函数实际上和addList是一样的,你可以把它缩短为addList = foldl1 (+)

【讨论】:

    【解决方案2】:

    除了柯里化,正如 sepp2k 指出的那样,这里我们使用所谓的eta reduction。它是 lambda 演算的约简规则之一,是 Haskell 的基础。当x 没有出现在f 中时,它表示\x -> f x 等同于f

    让我们将其应用于您的案例。我猜你对addList xs = foldl1 (+) xs 这样的定义感到满意。我们可以将其重写为 addList = \xs -> foldl1 (+) xs,现在应用 eta 缩减规则,我们得到 addList = foldl1 (+)

    此规则基于这样的想法:如果两个函数在应用于相同的参数时给出相同的结果,则它们是相等的。这里的两个函数是fg = \x -> f x,其中f : a -> b 并且我们希望为所有c : af c = g c 展示这一点。为了证明它需要一个任意的c : a 并将其应用于g:g c = (\x -> f x) c = f c,最后一个相等是通过另一个称为 beta 缩减的规则,它表示函数应用是通过替换来评估的。

    【讨论】:

      【解决方案3】:

      sepp2k 的解释是正确的,我只想指出(双关语)这种柯里化的应用有一个名字:它被称为“无点风格”。这是一个很好的解释,包括利弊:http://www.haskell.org/haskellwiki/Pointfree

      【讨论】:

        猜你喜欢
        • 2019-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-17
        相关资源
        最近更新 更多