没有让他们使用它们我不太确定所有lambdas / blocks都可以用于(除了map / collect / do /轻量级本地函数语法)。如果有些人可以发布一些有趣但有些可理解的例子(有解释)。
示例的首选语言:python,smalltalk,haskell
答案 0 :(得分:2)
您可以使用lambdas创建功能数据结构。这是一个简单的 - 功能列表(Python),支持add
和contains
方法:
empty = lambda x : None
def add(lst, item) :
return lambda x : x == item or lst(x)
def contains(lst, item) :
return lst(item) or False
我只是为了好玩而快速编码 - 请注意,您不能按原样添加任何虚假值。它也不是尾递归的,因为一个好的功能结构应该是。为读者练习!
答案 1 :(得分:2)
您可以将它们用于控制流程。例如,在Smalltalk中,“ifTrue:ifFalse:”方法是布尔对象上的一种方法,对True和False类中的每一个都有不同的实现。表达式
someBoolean ifTrue: [self doSomething] ifFalse: [self doSomethingElse]
在Smalltalk语法的[方括号]中使用两个闭包---块,一个用于真正的分支,一个用于假分支。对于类True的实例,“ifTrue:ifFalse:”的实现是
ifTrue: block1 ifFalse: block2
^ block1 value
,对于False类:
ifTrue: block1 ifFalse: block2
^ block2 value
此处的闭包用于延迟评估,以便可以在没有任何专门语法的情况下进行关于控制流的决策(除了块的语法)。
Haskell有点不同,它的懒惰评估模型在很多情况下有效地自动产生闭包的效果,但在Scheme中你最终使用lambdas来控制流量很多。例如,这是一个从关联列表中检索值的实用程序,在不存在该值的情况下提供可选计算的默认值:
(define (assq/default key lst default-thunk)
(cond
((null? lst) (default-thunk)) ;; actually invoke the default-value-producer
((eq? (caar lst) key) (car lst))
(else (assq/default key (cdr lst) default-thunk))))
它将被称为:
(assq/default 'mykey my-alist (lambda () (+ 3 4 5)))
这里的关键是使用lambda来延迟默认值的计算,直到它实际上已知是必需的。
另请参阅continuation-passing-style,它将此视为极端。例如,Javascript依赖于continuation-passing-style和closures来执行所有阻塞操作(如休眠,I / O等)。
ETA :我上面说的闭包,我的意思是词法范围闭包。通常,这是词汇范围的关键。
答案 2 :(得分:1)
你可以使用lambda来创建一个Y Combinator,它是一个接受另一个函数并返回它的递归形式的函数。这是一个例子:
def Y(le):
def _anon(cc):
return le(lambda x: cc(cc)(x))
return _anon(_anon)
这是一个 思想打击 ,值得更多解释,但不是在这里反复检查this blog entry(上面的样本也来自那里)。
答案 3 :(得分:1)
它的C#,但每次我读到它时,我个人都会对这篇文章有所了解:
Building Data out of Thin Air - 在C#中实现Lisp的cons,car和cdr函数。它展示了如何完全用lambda函数构建一个简单的堆栈数据结构。
答案 4 :(得分:1)
与haskell等相同的概念并不是真的相当,但在C#中,lambda构造具有(可选)编译为表示代码的 objcet模型的能力< / em>(表达式树)而不是代码本身(这本身就是LINQ的基石之一)。
这反过来会导致一些非常富有表现力的元编程机会,例如(这里的lambda表示“给定服务,你想用它做什么?”):
var client = new Client<ISomeService>();
string captured = "to show a closure";
var result = client.Invoke(
svc => svc.SomeMethodDefinedOnTheService(123, captured)
);
(假设合适的Invoke
签名)
这种类型的东西有很多用途,但我用它来构建一个不需要任何运行时代码生成的RPC堆栈 - 它只是解析表达式树,找出调用者的意图,将其转换为RPC,调用它,收集响应等(更多地讨论here)。
答案 5 :(得分:0)
Haskell中使用数值近似来计算单个变量函数的导数的一个例子:
deriv f = \x -> (f (x + d) - f x) / d
where
d = 0.00001
f x = x ^ 2
f' = deriv f -- roughly equal to f' x = 2 * x