练习lambda抽象的一部分

时间:2011-03-14 12:40:26

标签: haskell abstraction lambda

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

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

这个练习部分是什么?我们可以创建普通函数并在map函数参数中设置它。仅用于减少代码?那么为什么会出现这种抽象。减少代码并不重要。为什么呢?

谢谢。

5 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

有两种方法可以解释这个问题。第一个是为什么在我们写

时写map (\x -> x * x)
doubleIt x = x * x
... map doubleIt ...

答案是你可能有以下内容:

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

然后没有完全直接的转换,允许你将匿名函数完全浮动到顶层。

我们可以写

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

然后我们发现powerIt y = \x -> x^y! (当然,你可以将x浮动到外部定义,但在这种情况下,你实际上想要(虽然语法上Haskell不会让你)将(powerIt y)写为(\x -> powerIt y x)

当你有一流的功能时,他们需要来关闭他们的环境,这意味着你需要一些方式来引入一个可以引用其中的东西的函数声明它的词法范围。这就是lambdas的力量!

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

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

在这种情况下,请仔细考虑真正意味着什么。实际上,我们可以通过以下方式将let转换为几个lambdas:foo ys zs = (\powerIt -> map powerIt zs) (\x -> x^y)

现在,在实际实现中,这些desugarings并非都以这种方式发生,并且有时不同的子句被编译器以不同的方式处理,原因涉及效率。但核心的东西仍然存在 - lambdas是非常强大和令人费解的,并且可以为我们提供一种简单易于推理的核心语言,尽管我们将各种各样的绑定形式放在它们之上。

没有lambdas,我们有一种语言,我们可以定义变量,我们可以定义函数,然后我们有时可以用函数做某些事情。对于lambda,我们有一种语言,其中函数的值就像任何其他值一样,我们有一套统一的方法可以为任何事物赋值。

透视的反转是看lambda不是一个特例,而是作为一般情况,以及我们所有其他各种名称绑定机制作为它们的糖。

答案 2 :(得分:2)

你经常遇到这种情况,你需要一个非常专业的功能。它仅用于软件的这一部分。因此,给它一个具体的名称是没有任何意义的。

答案 3 :(得分: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) ....无论如何

另一个例子是desugared monadic符号。

例如,

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

(该代码可能存在错误,但无论如何我都不会写错误)

答案 4 :(得分:0)

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

嗯,编程语言中的Lambda函数派生自Lambda calculus,这是一个正式的函数定义系统。正如维基百科所说,Lambda演算是由Alonzo Church在20世纪30年代引入的,作为对数学基础的调查的一部分。它具有广泛的应用,而不仅仅是计算机科学。

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