首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Curried函数在方案中的实现

Curried函数在方案中的实现
EN

Stack Overflow用户
提问于 2008-12-10 19:48:44
回答 3查看 1.8K关注 0票数 2

当我执行以下操作时会发生什么?

代码语言:javascript
复制
(define ((func x) y)
    (if (zero? y)
        ((func x) 1)
        12))

我知道我可以这样做:

代码语言:javascript
复制
(define curried (func 5))

现在我可以用了。我感兴趣的是函数的定义。这条线

代码语言:javascript
复制
((func x) 1)

创建一个以x为参数的新lambda,然后在1上调用它?或者它比这更聪明,它只是重用了现有的。(例如,如果我执行(curried 0),则((func x) 1)行将等同于(curried 1) - PLAI Scheme是否执行此操作?)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2008-12-11 15:01:36

在方案标准中,规定了

代码语言:javascript
复制
(define (f x) 42) is short for (define f (lambda (x) 42)) .

自然(非标准)概括意味着:

代码语言:javascript
复制
(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-svn5dec20083m。语言:模块,内存限制:384MB。

(定义((f x) y) (列表x y)) (f 1) ((f 1) 2) (1 2)

如果我们命名临时值,可能会更容易看到发生了什么:

(定义h (f 1)) (h 2) (1 2) (h 3) (1 3)

由于"PLAI Scheme“是在DrScheme中实现的,我相信它继承了这个快捷表示法。

票数 8
EN

Stack Overflow用户

发布于 2008-12-10 20:03:52

我已经很久没有使用方案了,但是你可能会发现this article很有帮助。它描述了两个宏的实现,c-lambda和c-define,这两个宏允许对lambda表达式进行隐式curried定义。

票数 2
EN

Stack Overflow用户

发布于 2008-12-11 17:46:42

soegaard的答案是正确的--这是传统的扩展。然而,drscheme是聪明的!

我发现下面的代码在运行时间上是等效的:

原始来源:

代码语言:javascript
复制
(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]))

尝试优化:

代码语言:javascript
复制
(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))

大量使用此函数的代码(多次,而不仅仅是一次)在两个版本中都以1800ms的速度运行。更有趣的是,这个版本(我对正在发生的事情的可视化):

代码语言:javascript
复制
(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,那么肯定会出现速度减慢的情况,但快捷键表示法似乎不是这样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/357353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档