【问题标题】:Higher order functions and lack of recursion高阶函数和缺乏递归
【发布时间】:2014-08-16 16:01:03
【问题描述】:

我刚刚开始我的 Haskell 之旅,直到我遇到柯里化、部分应用程序和高阶函数(即当它开始变得有趣时)我一直在飞行 - 是的,我知道介绍的东西很简单,所以大概是这玩意吧!)

无论如何,这个问题是关于高阶函数的。 这个例子来自一个著名的教程

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

我可以看到它是如何工作的,如果我暂停我的怀疑,我相信我理解它。但是,让我感到困惑的是,为什么这不会递归。当我们重新进入回调函数时调用 f (f x),我们肯定会再次进行模式匹配。我在这里想念什么?

【问题讨论】:

  • 递归将在自身内部调用applyTwice,而不是两次调用参数函数。

标签: haskell recursion higher-order-functions


【解决方案1】:

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

square :: Int -> Int
square x = x * x

现在我们来看看下面函数应用的评估:

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

【讨论】:

  • 有趣的事实:大多数 Haskeller 可能会定义 applyTwice,因此它看起来与 square 几乎相同,即 applyTwice f = f . f。也许这更清楚地表明没有递归正在进行,因为基本上我们只是“平方”一个函数。 (或者更确切地说,加倍,如果这是我们正在谈论的教堂数字。)
  • @leftaroundabout 考虑到两个示例中涉及的代数结构,这并非巧合。
  • @leftaroundabout 或者取决于您认为内同态幺半群是加法还是乘法。 ;)
【解决方案2】:

这不会递归,因为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 变成incx 变成3 时,我们看到applyTwice 所做的只是获取它的第一个参数,然后将它两次应用于它的第二个参数。

【讨论】:

  • 道歉我一直是个白痴,我不知道为什么我认为 applyTwice 本身被调用了。睡眠可能是这里的良药!
猜你喜欢
  • 2014-01-22
  • 1970-01-01
  • 2020-04-04
  • 2018-04-02
  • 1970-01-01
  • 2021-11-01
  • 2021-10-24
  • 1970-01-01
  • 2019-08-06
相关资源
最近更新 更多