如何在Haskell中了解嵌套Lambda函数

Sav*_*emp 1 haskell functional-programming

我试图了解Haskell中以下2个lambda表达式的含义:

f = \x -> x (\y -> x y)
g = \x -> (\y -> y) x
Run Code Online (Sandbox Code Playgroud)

我试图将它们转换,然后得到了:

f x y = x x y
g x y = y x
Run Code Online (Sandbox Code Playgroud)

它是否正确?我假设两个函数的参数都必须是x和y,因为它们都可以在函数描述的lambda表达式中找到。我基本上是这样理解的:f(x)= xf(y)和f(y)= y x。对于g,g(x)= g(y)x和g(y)= y。但是,由于我是Haskell的新手,所以我对这些类型的转换不是很自信。如果不正确,什么是正确的转换?

chi*_*chi 5

都不正确。您的解决方案使用功能

f x y = x x y
g x y = y x
Run Code Online (Sandbox Code Playgroud)

这实际上意味着

f = \x -> (\y -> x x y)
g = \x -> (\y -> y x)
Run Code Online (Sandbox Code Playgroud)

那些与原始表达方式不同

f = \x -> x (\y -> x y)
g = \x -> (\y -> y) x
Run Code Online (Sandbox Code Playgroud)

上面两个方程可以改写为

f x = x (\y -> x y)
g x = (\y -> y) x
Run Code Online (Sandbox Code Playgroud)

但是从这里开始,没有办法将其余的lambda变成更多针对f或的参数g。充其量,我们可以使用beta / eta转换来简化它们,并获得

f x = x x            -- eta  (\y -> x y) = x
g x = x              -- beta (\y -> y) x = x
Run Code Online (Sandbox Code Playgroud)

(另请参阅以下Will Ness的评论,他指出,通过额外扩展eta,f我们可以达到OP的定义。但这仍然是偶然的。)

最后,请注意,Haskell不会接受,f x = x x因为无法键入,除非我们使用等级2类型并显式提供类似的类型注释f :: (forall a. a) -> b。原始代码也f = \x -> x (\y -> x y)遇到同样的问题。在无类型语言中也可以,例如编程语言理论中的无类型lambda演算。

  • 稍微严格一点:`fx = xx`可以用rank-2类型键入(因此在GHC中,但是在标准Haskell中不是),但是不能推断出来。 (2认同)
  • “ fxy = xxy”等同于正确的定义,因此不要完全错。但是,“派生”是完全没有的。 (2认同)