Haskell:在连续传递风格中完全定义阶乘的问题
我一直试图在一大堆内容中理解函数式编程、Haskell 和延续传递风格,而我的结构化/OOP 背景给我带来了困难。
根据 this 我理解以下应该是 CPS 风格中阶乘的正确定义:
factorial n = fact n id where id = \x -> x
fact 0 cont = cont n
fact (n+1) cont = fact n * (n + 1)
但我不确定最后的“* (n + 1)”部分 - 这是正确的吗?
I've been trying to understad Functional Programming, Haskell and Continuation Passing Style in one big blob and my structured/OOP background is giving me a hard time.
According to this I understand the following should be a correct definition of factorial in CPS-style:
factorial n = fact n id where id = \x -> x
fact 0 cont = cont n
fact (n+1) cont = fact n * (n + 1)
but I'm not sure about the "* (n + 1)" part at the end - is that correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它不太正确(并且不适合我编译);值
n+1
是正确的,但它的使用方式不正确。也许您想使用操作符部分?这与下面的内容相同(但更迟钝),
我将在这里更改一些内容。首先,
id
是一个标准函数,因此您不需要重新定义它。其次,这些示例使用“n+k 模式”,IIRC 在 GHC 中默认不再可用。您可以使用普通模式变量来代替“n+k 模式”。请注意,我使用1
作为基本情况;如果您从n
开始倒数,并且应该在计算中的每个步骤应用延续函数(您已将其从归纳步骤中删除),那么这更容易推理。记住这些,你就可以写出我认为或多或少地道的内容。
编辑:我个人不喜欢 n+k 模式,但我想我需要花点时间来解释它们。我发现如果你考虑带有基本情况和归纳步骤的数学归纳法,就更容易理解。基本情况是
事实 0 ...
。然后,您可以从基本步骤开始定义其他值:“对于任何fact n k
,通过此关系确定fact (n+1) k
”。这与我对正常模式变量的看法不同,即自上而下而不是像这里一样自下而上,但我认为它解释了动机以及为什么有些人喜欢这种风格。我不喜欢 n+k 模式的原因只是因为我发现定义更混乱,但是 YMMV。
It's not quite correct (and doesn't compile for me); the value
n+1
is right but it isn't used in quite the correct way. Maybe you meant to use an operator section?This is identical to (but more obtuse than) the following
There are a few things I would change here. First,
id
is a standard function so you don't need to redefine it. Secondly, these examples use "n+k patterns", which IIRC are no longer available by default in GHC. Instead of an "n+k pattern", you can use a normal pattern variable. Note that I used1
for the base case; this is simpler to reason about if you're counting down fromn
, and the continuation function should be applied at each step within the computation (you'd dropped it from the induction step). With these in mind, you can writewhich I would consider more or less idiomatic.
Edit: I personally don't like n+k patterns, but I thought I'd take a bit of time to explain them. I find it easier to follow if you think of mathematical induction with a base case and an induction step. The base case is
fact 0 ...
. You then define the other values by proceeding from the base step: "for anyfact n k
, determinefact (n+1) k
by this relation." This is different from how I think of normal pattern variables, that is top-down instead of bottom-up as here, but I think it explains the motivation and why some people like the style.The reason I don't like n+k patterns is simply because I find the definitions more cluttered, but YMMV.