请您给我解释一下,当涉及到高阶函数时,curry是如何工作的,特别是下面的例子



谁能帮我解决下面的问题,

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

我不明白上面是如何工作的。如果有(+3) 10肯定会生成13吗?那是什么f (f x)?基本上,当涉及到高阶函数时,我不理解curry。

所以我不明白的是,如果说我们有一个形式为a -> a -> a的函数,它会输入a,然后产生一个函数,期望另一个输入a产生输出。因此,如果我们有add 5 3,那么执行add 5将产生一个函数,该函数期望输入3产生8的最终输出。我的问题是,这在这里是如何起作用的。我们把一个函数作为输入那么部分函数的应用在这里是像在add x y中那样工作还是我完全把一切都复杂化了?

这不是套用,这是局部应用。

> :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并不是一个真正的部分应用程序。这只是(+)对参数3的一个[常规]应用。

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

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

相关内容

最新更新