2016-12-06 72 views
1

我试图建立了解系列嵌入式匿名表达式,如最好的方法:了解Haskell中的嵌入式匿名函数?

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

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

(\x -> x + 1) 

其中指出,函数取一个号码,并返回一个数字: Num a => a -> a

但是当事情被嵌入这样我得到相当丢失。我试图理解它是,匿名函数管道的参数从fgx马上我应该开始编写输入,因为它是使用变量的地方。但我已经尝试了合理化四到五种不同的解释,并且我一直在抓住最内层函数中看起来像递归函数调用的东西。

这个问题的打字是否可以通过简单的方式解决?

回答

4

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

\f g x -> f (g x) 

在任一情况下,将所述函数应用于参数foo1的函数返回

\g x -> foo1 (g x) 

将此应用于函数foo2返回另一个功能

\x -> foo1 (foo2 x) 

其中,如果应用于另一个参数bar将返回由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 
+0

谢谢! 'f g x - > f(g x)'确实“固定”了我的观点。我现在明白了。 – Micrified

3

你不需要overthink这一点。 (\f -> (\g -> (\x -> f (g x))))只是一个参数的函数f某些结果 ......这又是一个函数,但它原则上与其结果是数字的函数没有区别。这只是一些黑盒...

\f -> ██ 

现在,当你真正该拉姆达适用于一些f,您可以访问的黑箱。例如,我可以把它应用到sqrt功能:

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

好了,另一个lambda这将产生一些黑盒。让我们看看用的是一个(^2)

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

既然黑箱是不是太黑暗:这只是f (g x),其中fgx是我们已经应用参数:

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

当然这就是只是一个例子。一般来说,你的大lambda需要两个函数,并给你两个函数的组合。当然,这是更好地写成

\f g x -> f $ g x 

或事实上根本.

+0

谢谢。我没有把它看作一个带有两个函数参数的函数组合。一旦我这样做,这是有道理的! – Micrified

1

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

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