Haskell 高阶函数和缺乏递归
我刚刚开始我的Haskell之旅,直到我遇到了Curry、部分应用程序和高阶函数(即,当它开始变得有趣时),我一直在飞——是的,我知道介绍的东西很简单,这东西可能也很简单!) 无论如何,这个问题是关于高阶函数的。 给出了一个著名教程中的示例Haskell 高阶函数和缺乏递归,haskell,recursion,higher-order-functions,Haskell,Recursion,Higher Order Functions,我刚刚开始我的Haskell之旅,直到我遇到了Curry、部分应用程序和高阶函数(即,当它开始变得有趣时),我一直在飞——是的,我知道介绍的东西很简单,这东西可能也很简单!) 无论如何,这个问题是关于高阶函数的。 给出了一个著名教程中的示例 applyTwice :: (a -> a) -> a -> a applyTwice f x = f (f x) 我可以看到它是如何运作的,如果我不再怀疑,我相信我理解它。然而,让我困惑的是,为什么这种情况不会再次发生。如果在我们重
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
。也许这更清楚地表明没有递归,因为基本上我们只是“平方”一个函数。(或者说是加倍,如果这是我们所讨论的教堂数字。)左撇子说,这两个例子中涉及的代数结构都不是巧合。@左撇子,或者取决于你是否认为自同态幺半群是加性的或乘法的。