了解 Haskell 中的嵌入式匿名函数?

Understanding embedded anonymous functions in Haskell?

我正在尝试建立理解一系列嵌入式匿名表达式的最佳方法,例如:

(\f -> (\g -> (\x -> f (g x) ) ) )

在Haskell。我对更简单的表达式没有太多麻烦,例如:

(\x -> x + 1) 

其中指出该函数接受一个数字和 returns 一个数字: Num a => a -> a

但是当事情像这样嵌入时,我就迷路了。我试图理解它是匿名函数立即将参数从 f 传递到 g 再到 x ,然后我应该开始编写类型,因为它是使用变量的地方.但我已经尝试合理化可能四五个不同的解释,并且我一直在关注最内层函数中看起来像递归函数调用的东西。

这个问题的类型可以用更简单的方式解决吗?

这只是柯里化的一个例子。 Haskell 为此提供语法糖:

\f g x -> f (g x)

在任何一种情况下,将函数应用于参数 foo1 return 函数

\g x -> foo1 (g x)

将其应用于一个函数 foo2 returns 另一个 函数

\x -> foo1 (foo2 x)

如果应用于 另一个 参数 bar 将 return 由 foo1 (foo2 bar).

计算的值

在Python这样的语言中,它看起来像

compose1 = lambda f: lambda g: lambda x: f(g(x))

因为 Python 函数默认不柯里化,这是一个独特的 来自 compose2 = lambda f,g,h: f(g(x)) 的函数。两者的区别 将是你如何使用它们。

compose1(foo1)(foo2)(bar)
compose2(foo1, foo2, bar)

使用 def 语句编写,compose1 看起来像

def compose1(f):
    def _1(g):
        def _2(x):
            return f(g(x))
        return _2
    return _1

你不必想太多。 (\f -> (\g -> (\x -> f (g x) ) ) ) 只是参数 f 一些结果 ... 的函数,这恰好又是一个函数,但原则上它与函数没有什么不同结果是一个数字。这只是一些黑匣子...

\f -> ██

现在,当您实际将此 lambda 应用于某些 f 时,您可以访问黑盒。例如,我可以将它应用于 sqrt 函数:

(\f -> ██) sqrt
  ≡ ██
  = \g -> ██₂

好的,另一个产生一些黑盒的 lambda。让我们将那个应用到 (^2)

(\g -> ██₂) (^2)
  ≡ ██₂
  = \x -> ██₃

现在 blackbox 不是那么黑了:它只是 f (g x),其中 fgx 是我们已经应用的参数:

(\f -> (\g -> (\x -> f (g x) ) ) ) sqrt (^2)
  ≡ \x -> sqrt (x^2)

当然这只是一个例子。一般来说,你的那个大 lambda 有两个函数,并给你两个函数的组合。当然最好写成

\f g x -> f $ g x

或者实际上只是 .

将整个 lambda 函数想象成一个黑盒子。从签名中我们知道有三个箭头“->”分隔每个参数。这告诉你这个黑盒子接收到 3 个实参:f g x。它将 f 应用于将 g 应用于 x 的结果。通过查看其命名函数等价物更容易理解。

compose f g x = f (g x)
compose' f g = \x -> f (g x)