haskell - 如何在 Haskell 中编写递归 lambda 表达式?

标签 haskell recursion lambda

我不确定这是否是一种好的编程习惯,但我想知道是否可以使用 lambda 表达式定义递归函数。

这是我编的一个人为的例子:所以可以递归地定义Haskell中的阶乘函数如下

factorial :: Integer -> Integer 
factorial 1 = 1
factorial (n + 1) = (n + 1) * factorial n

现在,我想要一个函数 f这样f n = (factorial n) + 1 .而不是使用 factorial n 的名称(即事先定义),我想定义 f在哪里 factorial nf 的定义中给出了一个 lambda 表达式.我可以在 f 中使用递归 lambda 定义吗?代替使用名称阶乘?

最佳答案

使用纯 lambda 表达式进行递归的规范方法是使用定点组合器,它是具有属性的函数

fixpoint f x = f (fixpoint f) x

如果我们假设存在这样的组合子,我们可以将递归函数写成
factorial = fixpoint (\ff n -> if n == 1 then 1 else n * ff(n-1))

唯一的问题是 fixpoint本身仍然是递归的。在纯 lambda 演算中,有一些方法可以创建仅由 lambda 组成的定点组合器,例如经典的“Y 组合器”:
fixpoint f = (\x -> f (x x)) (\x -> f (x x))

但是我们仍然有问题,因为根据 Haskell,这个定义不是类型良好的——而且可以证明,仅使用 lambda 和函数应用程序是无法编写类型良好的定​​点组合器的。它可以通过使用辅助数据类型来完成某种类型的递归:
data Paradox a = Self (Paradox a -> a)
fixpoint f = let half (Self twin) = f (twin (Self twin))
             in half (Self half)

(请注意,如果删除了单例数据类型的注入(inject)和投影,这正是 Y 组合子!)

关于haskell - 如何在 Haskell 中编写递归 lambda 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7141229/

相关文章:

c# 表达式 lambda 到 vb.net

performance - 可变的(可能是并行的)Haskell 代码和性能调优

haskell - 获取haskell中字符串的所有旋转

Haskell:检查列表中的第一个元素是否重复

haskell - 尝试简单的单例示例时出现模板 Haskell 错误

c++ - 试图在递归函数 : Unhandled exception/Stack overflow 中捕获失败的分配

c++ - 递归函数的正确返回方式

Java 8 : Applying Stream map and filter in one go

c# - 递归创建自定义复杂对象

c++ - 将不可复制的闭包对象传递给 std::function 参数