2011-03-14 61 views
1

我是Haskell编程的新手。现在我正在学习lambda函数和lambda抽象。我想,lambda函数的实践部分是什么。例如,我们有:lambda抽象的练习部分

map(\x -> x * 2) [1,2,3,4,5] 
[2,4,6,8,10] 

这个练习部分是什么?我们可以创建正常的函数并将其设置为映射函数参数。仅用于代码缩减?那么为什么要提出这种抽象。代码缩减并不重要。为什么?

谢谢。

+0

我相信维基百科会回答你的问题。例如,请参见[函数式编程](http://en.wikipedia.org/wiki/Functional_programming)。 – 2011-03-14 12:48:53

+0

s /练习部分/实践目的/? – 2011-03-14 14:43:00

+0

不要忘了你可以写得更简洁:'map(* 2)[1..5]' – stusmith 2011-03-14 15:57:00

回答

4

有两种方法来解释这个问题。首先是为什么要写map (\x -> x * x)时,我们可以写

doubleIt x = x * x 
... map doubleIt ... 

答案存在,你可能有以下几点:

foo y zs = map (\x -> x^y) zs 

,然后没有完全straightfoward变换,允许您浮动匿名功能完全达到顶级水平。

我们可以写

foo y zs = map (powerIt y) xs 
powerIt y = ? 

,然后我们发现powerIt y = \x -> x^y! (当然,你可以将x浮动回外部定义,但在这种情况下,你实际上希望(尽管句法上Haskell不会让你)写(powerIt y)(\x -> powerIt y x)

当你有第一类函数他们需要关闭了他们的环境,这意味着你需要一些的方式介绍可参考的东西在声明它的词法范围的功能,这是lambda表达式的力量!

现在,另一个问题是为什么不将匿名函数浮动到不是顶级的适当级别,从而得到,例如

foo y zs = let powerIt x = x^z 
      in map powerIt zs 

在这种情况下,仔细考虑一下让真正意义的东西。事实上,我们可以改变让进了几个lambda表达式以下列方式:foo ys zs = (\powerIt -> map powerIt zs) (\x -> x^y)

现在,在实际实施中,这些desugarings不一切发生的正是这种方式,有时不同的条款获得通过编译器区别对待的原因涉及效率。但核心的东西仍然存在 - lambda是非常强大和宽容的,并且可以给我们一个简单易懂的核心语言,尽管我们在它们之上布置了各种各样的绑定形式。

没有lambda表达式,我们有一种语言,我们可以定义变量,我们可以定义函数,然后我们有时可以用函数做某些事情。使用lambda表达式我们有一种语言,其功能就像其他任何值一样,我们有一套统一的方式来为任何东西分配名称。

透视的反转是将lambda看作不是特殊情况,而是作为一般情况,以及我们所有其他各种各样的名称约束机制作为它们的糖。

+0

我应该注意到,历史上,让我们不像上面那样转换成lambdas的原因是让绑定是多态的,而lambda函数的参数默认是单形的。但现代ghc消除了让绑定的默认泛化,这使得转换更直接。 – sclv 2011-03-15 13:54:17

4

并不是所有的功能都被广泛使用来“配”一个名字。例如,如果您只使用此功能一次,对于此特定地图,您可能不希望为其指定名称,因为您再也不会使用它。

2

你经常面对的情况,你需要一个非常专业的功能。它被用在你的软件的这个部分,只在那里。因此,给它一个具体的名字没有任何意义。

2

可读性;你可以有(牵强,但要说明这一点)

map (\x -> x * 2) . anotherfunction . anotheragain . itgoesonandon $ 
[ a lont list ] 

VS

map f . anotherfunction . anotheragain . itgoesonandon $ 
[ a lont list ] 
    where f x = x * 2 

这是品味的问题,但在第一种情况下,你马上知道你是什么函数映射,在第二你必须在源代码中找到f,它可能在几行之外。

顺便说一句,我会写map (*2) ....反正

另一个例子是脱单子符号。

例如,

do a <- action1 
    b <- action2 
    action3 
    c <- action4 a b 
    action5 c 

变为:

action1 >>= \a -> action2 >>= \b -> action3 >> action4 a b >>= \c -> action5 c 

VS

action1 >>= a2 
    where a2 a = action2 >>= a3 
      where a3 b = action3 >> action4 a b >>= a4 
        where a4 c = action5 c 

(有可能是在代码中的错误,但我绝不会写反正)

0

如果我正确理解你的问题,你问为什么有人会想出在特定的编程语言范围之外的Lambda函数的抽象,是正确的?

那么,编程语言中的lambda函数来自Lambda calculus,这是一个用于函数定义的正式系统。正如维基百科所说,Lambda微积分在20世纪30年代由Alonzo Church引入,作为对数学基础进行调查的一部分。它具有广泛的应用范围,不仅仅在计算机科学领域。

正如上述评论者所指出的,Functional programming是Lambda演算的根源。我只能建议你阅读维基百科中的相关条目,这里有一些非常有趣的信息;-)。