-
21-08-2019 - |
题
当我这样做时,会发生什么?
(define ((func x) y)
(if (zero? y)
((func x) 1)
12))
我明白,我可以做到这一点:
(define curried (func 5))
和现在我可以使用咖喱。我很好奇的是函数的定义。是否线
((func x) 1)
创建以x作为参数一个新的拉姆达,然后调用它上1?或者比它更聪明,它只是重新使用现有的一个。 (例如,如果我做(curried 0)
,所述((func x) 1)
线将相当于(curried 1)
- ?不PLAI方案做到这一点)
解决方案
在Scheme标准中,规定
(define (f x) 42) is short for (define f (lambda (x) 42)) .
在天然(非标)概括意味着:
(define ((f x) y) (list x y)) is short for (define (f x) (lambda (y) (list x y)))
which is short for (define f (lambda (x) (lambda (y) (list x y))))
要测试它,让我们尝试在DrScheme的示例
欢迎到DrScheme,版本4.1.3.3-svn5dec2008 [3米]。 语言:模块;存储器极限:384兆字节
(定义((F X)Y)(表X Y)) (F 1)
((F 1)2) (1 2)
如果我们命名临时值,它可能是更容易地看到发生了什么:
(规定h(F 1)) (H 2) (1 2) (H 3) (1 3)
由于“PLAI计划”中DrScheme被实现,相信它继承该快捷方式表示法。
其他提示
它已经太长时间,因为我有计划的工作,但你可能会发现这篇文章很有帮助。 它描述了两个宏,C-拉姆达和执行的c-限定其允许lambda表达式的隐式咖喱定义。
soegaard的答案是正确的 - 这是传统的扩张。然而,drscheme很聪明!
下面的代码我已经发现在运行时间当量:
原始来源:
(define ((substitute lv value) e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons ((substitute lv value) f)
((substitute lv value) r))])]
[(cons? e)
(cons ((substitute lv value) (car e))
((substitute lv value) (cdr e)))]
[else e]))
在尝试优化:
(define (substitute lv value)
(local ([define inner
(lambda (e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons (inner f)
(inner r))])]
[(cons? e)
(cons (inner (car e))
(inner (cdr e)))]
[else e]))])
inner))
一个大量使用此函数(多次,不只是一次)的代码,在1800毫秒两个版本运行。更有意思的是,这个版本(我发生了什么事的可视化):
(define (substitute lv value)
(local ([define inner
(lambda (e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons ((substitute lv value) f)
((substitute lv value) r))])]
[(cons? e)
(cons ((substitute lv value) (car e))
((substitute lv value) (cdr e)))]
[else e]))])
inner))
在2000毫秒运行。所以肯定是有放缓,如果调用替代内代替分别创建一个lambda,但现在看来,这是不符合快捷符号的情况。
不隶属于 StackOverflow