首页 > 解决方案 > 请您向我解释一下高阶函数的柯里化是如何工作的,尤其是下面的示例

问题描述

有人可以帮我解决以下问题,

applyTwice :: (a -> a) -> a -> a  
applyTwice f x = f (f x)

我不明白上述是如何工作的。如果我们有类似的东西(+3) 10肯定会产生13?那是怎么回事f (f x)。基本上,在查看高阶函数时,我不理解柯里化。

所以我不明白的是,如果说我们有一个形式的函数,a -> a -> a它将接受一个输入a然后产生一个函数,该函数期望另一个输入 a 产生一个输出。因此,如果我们add 5 3这样做add 5,将产生一个函数,该函数期望输入3产生最终输出8。我的问题是这里是如何工作的。我们将一个函数作为输入,所以部分函数应用程序在这里是否像在其中一样工作,add x y或者我是否完全过度复杂化了一切?

标签: functionhaskellcurrying

解决方案


那不是柯里化,那是部分应用。

> :t (+)
(+) :: Num a => a -> a -> a

> :t (+) 3
(+) 3 :: Num a =>    a -> a

部分应用程序(+) 3确实产生了一个函数(+3)(*),它等待另一个数字输入来产生它的结果。它会这样做,无论是一次还是两次

您的示例扩展为

applyTwice (+3) 10 = (+3) ((+3) 10) 
                   = (+3) (10+3)
                   =      (10+3)+3

这里的所有都是它的。


(*)(实际上是(3 +),但(+ 3)无论如何都一样)。


正如chepner评论中澄清的那样(引用最少的复制编辑),

部分应用是由于函数只接受一个参数,以及函数应用的右结合性(->)和左结合性的结合而产生的一种错觉。(+) 3并不是真正的部分应用程序。(+)这只是对 a argument的 [常规] 应用3

因此,从其他更传统的语言的角度来看,我们将其称为柯里化和部分应用之间的区别。

但从 Haskell 的角度来看,这确实是关于柯里化,即一次将一个函数应用于其参数,直到其类型指示完全饱和(即a->a->a应用于一个值的a值变成一个a->a值,然后再变成一个a值当a依次应用于一个值时)。


推荐阅读