Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 高阶函数和缺乏递归_Haskell_Recursion_Higher Order Functions - Fatal编程技术网

Haskell 高阶函数和缺乏递归

Haskell 高阶函数和缺乏递归,haskell,recursion,higher-order-functions,Haskell,Recursion,Higher Order Functions,我刚刚开始我的Haskell之旅,直到我遇到了Curry、部分应用程序和高阶函数(即,当它开始变得有趣时),我一直在飞——是的,我知道介绍的东西很简单,这东西可能也很简单!) 无论如何,这个问题是关于高阶函数的。 给出了一个著名教程中的示例 applyTwice :: (a -> a) -> a -> a applyTwice f x = f (f x) 我可以看到它是如何运作的,如果我不再怀疑,我相信我理解它。然而,让我困惑的是,为什么这种情况不会再次发生。如果在我们重

我刚刚开始我的Haskell之旅,直到我遇到了Curry、部分应用程序和高阶函数(即,当它开始变得有趣时),我一直在飞——是的,我知道介绍的东西很简单,这东西可能也很简单!)

无论如何,这个问题是关于高阶函数的。 给出了一个著名教程中的示例

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

我可以看到它是如何运作的,如果我不再怀疑,我相信我理解它。然而,让我困惑的是,为什么这种情况不会再次发生。如果在我们重新进入回调时调用f(fx),我们肯定会再次进行模式匹配。我错过了什么

递归是在自己的定义中应用函数。在这里,我们没有这种情况。让我们看看如果我们定义一个函数
square
并将其与
applyTwice
一起使用会发生什么:

square :: Int -> Int
square x = x * x
现在,让我们了解以下函数应用程序的评估:

applyTwice square 3 => square (square 3) => square 9 => 81

这不会递归,因为不会递归调用
applyTwice
。这可能有点重复,所以让我们看一下评估跟踪

inc :: Int -> Int
inc n = n + 1

applyTwice inc 3
(\f x -> f (f x)) inc 3
(\x -> inc (inc x)) 3
inc (inc 3)

f
变成
inc
x
变成
3
时,我们看到
applyTwice
所做的一切就是取第一个参数,然后对第二个参数应用两次。

递归将从内部调用
applyTwice
,而不是两次参数函数。抱歉,我是个白痴,我不知道为什么我认为applyTwice被称为内在的。睡眠也许是这里的良药!有趣的事实:大多数Haskeller可能会定义
applyTwice
,因此它看起来几乎与
square
相同,即
applyTwice f=f。f
。也许这更清楚地表明没有递归,因为基本上我们只是“平方”一个函数。(或者说是加倍,如果这是我们所讨论的教堂数字。)左撇子说,这两个例子中涉及的代数结构都不是巧合。@左撇子,或者取决于你是否认为自同态幺半群是加性的或乘法的。