首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于callCC的澄清

关于callCC的澄清
EN

Stack Overflow用户
提问于 2019-12-09 10:42:08
回答 1查看 90关注 0票数 0

我的背景是Javascript,Python &一点Haskell。嗨,我是新加入的方案(1天大)。我想了解下面两个代码片段之间的区别。

代码语言:javascript
复制
(define onePlus (lambda (v) (+ 1 v)))
(onePlus 4) ; 5 

使用CallCC

代码语言:javascript
复制
(define anotherOnePlus 0)
(+ 1 (call/cc (lambda (k) (set! anotherOnePlus k) (k 4)))) ; 5
(anotherOnePlus 4); 5

为什么有人想要做第二种方法来获得你所居住的功能。在更大的图景中,我遗漏了什么?

获取函数的范围有什么限制吗?

代码语言:javascript
复制
(define temp 0)
(+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! temp k) (k 4)))))) ; 10
(temp 5) ; 11

在这里它看起来绝对像JS中的h => 1 + 2 + 3 + h。如果我想要在(+ 3 h)上获得它,这意味着我需要在单独的行中编写它?

EN

回答 1

Stack Overflow用户

发布于 2019-12-15 22:45:07

如果你要用不同的值一遍又一遍地计算,那么做第二个就是唯一的理由。实际上,它是一个goto,如果你的延续没有被分隔,它就是一个无限循环。例如:试试这个:

代码语言:javascript
复制
(define anotherOnePlus 0)
(let ()
  (+ 1 (call/cc (lambda (k) (set! anotherOnePlus k) (k 4)))) ; 5
  (anotherOnePlus 4)); 5

你永远得不到答案,因为(anotherOnePlus 4)会把你带回带有延续(anotherOnePlus 4)(+ 1 4),这会让你再次回到正题。

该函数没有限制。只要它被引用,它就不会被垃圾回收。

演示call/cc的更好方法是使用更好的示例。如果您要实现具有多个列表的map,则需要获取cars,除非其中一个列表为空,那么结果应该为空。您可以通过首先迭代整个列表来完成此操作,确保没有空列表:

代码语言:javascript
复制
(define (cars-1 lsts)
  (define (have-elements? lsts)
    (cond ((null? lsts) #t)
          ((null? (car lsts)) #f)
          (else (have-elements? (cdr lsts)))))
  (define (cars lsts)
    (if (null? lsts)
        '()
        (cons (caar lsts)
              (cars (cdr lsts)))))
  (if (have-elements? lsts)
      (cars lsts)
      '()))

但是有一个聪明的解决方案,你只要这样做,如果你发现一个空的元素,你就会放弃。这可以通过像下面这样的延续来实现:

代码语言:javascript
复制
(define (cars lsts)
  (define (cars lsts k)
    (cond ((null? lsts) (k '()))
          ((null? (car lsts)) '())
          (else (cars (cdr lsts)
                      (lambda (res)
                        (k (cons (caar lsts)
                              res)))))))
  (cars lsts values))

现在,如果我们可以让语言进行延续,并且我们可以选择是否使用它们,那不是很好吗?Scheme为您做到了这一点。你可以这样写它:

代码语言:javascript
复制
(define (cars lsts)
  (call/cc
   (lambda (bail)
     (define (cars lsts)
       (cond ((null? lsts) '())
             ((null? (car lsts)) (bail '()))
             (else (cons (caar lsts)
                         (cars (cdr lsts))))))
     (cars lsts))))

现在,如果你看一下SRFI-1 List library的参考实现,你会发现他们实际上是这样做的。

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

https://stackoverflow.com/questions/59241878

复制
相关文章

相似问题

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