标签: continuation-passing

延续和回调之间有什么区别?

我一直在浏览整个网络,寻找关于延续的启示,并且令人难以置信的是,最简单的解释如何能够如此完全混淆像我这样的JavaScript程序员.当大多数文章使用Scheme中的代码解释延续或使用monad时尤其如此.

现在我终于认为我已经理解了延续的本质,我想知道我所知道的是否真的是事实.如果我认为真实的事实并非如此,那么它就是无知而不是启蒙.

所以,这就是我所知道的:

在几乎所有语言中,函数显式地将值(和控制)返回给它们的调用者.例如:

var sum = add(2, 3);

console.log(sum);

function add(x, y) {
    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

现在,在具有第一类函数的语言中,我们可以将控制和返回值传递给回调,而不是显式返回给调用者:

add(2, 3, function (sum) {
    console.log(sum);
});

function add(x, y, cont) {
    cont(x + y);
}
Run Code Online (Sandbox Code Playgroud)

因此,不是从函数返回值,而是继续使用另一个函数.因此,这个函数被称为第一个的延续.

那么延续和回调之间的区别是什么?

javascript continuations callcc continuation-passing

125
推荐指数
3
解决办法
2万
查看次数

两个延续如何相互抵消?

我正在阅读有关列表操作的一些技巧,其中包含以下内容:

zipRev xs ys = foldr f id xs snd (ys,[])
  where
    f x k c = k (\((y:ys),r) -> c (ys,(x,y):r)) 
Run Code Online (Sandbox Code Playgroud)

我们在这里可以看到,我们有两个连续的叠放在一起。发生这种情况时,他们通常可以“取消”,如下所示:

zipRev xs ys = snd (foldr f (ys,[]) xs)
  where
    f x (y:ys,r) = (ys,(x,y):r)
Run Code Online (Sandbox Code Playgroud)

我不明白您如何“取消”堆叠的延续以从顶部的代码块到达底部的代码块。您寻找进行这种转换的方式是什么,为什么会起作用?

continuations haskell fold continuation-passing

31
推荐指数
2
解决办法
1429
查看次数

25
推荐指数
3
解决办法
5211
查看次数

为什么延续传球风格

在Kent Dybvig(第4版)第3.4节的计划编程语言中,他非常清楚地描述延续传递方式是什么.对于为什么他给出了两个原因:

  1. 将多个结果传递给它的continuation,因为实现continuation的过程可以接受任意数量的参数.
  2. CPS还允许一个过程采用单独的延续......,它可以接受不同数量的参数.

由于第一个原因也可以使用values程序和第二个使用case-lambda,我不清楚使用延续传递样式的优点.有人可以告诉我一些关于延续传递风格是否合适的例子,它使代码更好,更清晰等等?

scheme continuations continuation-passing

23
推荐指数
2
解决办法
4117
查看次数

如何使用call/cc实现c#5.0中的新异步功能?

我一直在关注asyncc#5.0中新功能的新公告.我对继续传递样式以及新的c#编译器对Eric Lippert的帖子中的代码片段所做的转换有基本的了解:

async void ArchiveDocuments(List<Url> urls)
{
  Task archive = null;
  for(int i = 0; i < urls.Count; ++i)
  {
    var document = await FetchAsync(urls[i]);
    if (archive != null)
      await archive;
    archive = ArchiveAsync(document);
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道有些语言通过call-with-current-continuation(callcc)本地实现continuation ,但我真的不明白它是如何工作的或它究竟是做什么的.

所以这就是问题:如果安德斯等人.已经决定咬紧牙关,只是callcc在c#5.0而不是async/ await特殊情况下实现,上面的代码片段会是什么样子?

c# asynchronous callcc continuation-passing async-await

19
推荐指数
1
解决办法
2821
查看次数

是否继续传递风格与管道有什么不同?

我一直在学习延续传递样式,特别是在javascript中实现的异步版本,其中一个函数将另一个函数作为最终参数并创建一个异步调用,将返回值传递给第二个函数.

但是,我不能完全看到延续传递除了重新创建管道(如在unix命令行管道中)或流之外还有什么作用:

replace('somestring','somepattern', filter(str, console.log));
Run Code Online (Sandbox Code Playgroud)

VS

echo 'somestring' | replace 'somepattern' | filter | console.log
Run Code Online (Sandbox Code Playgroud)

除了管道更多,更清洁.使用管道,很明显数据被传递,同时执行被传递给接收程序.事实上,对于管道,我希望数据流能够继续向下传递管道,而在CPS中我期望一个串行过程.

或许可以想象,如果通信对象和更新方法与数据一起传递,CPS可以扩展到连续管道,而不是完整的切换和返回.

我错过了什么吗?CPS在某些重要方面有所不同(更好吗?)?

要清楚,我的意思是继续传递,其中一个函数将执行传递给另一个函数,而不仅仅是普通的回调.CPS似乎暗示将函数的返回值传递给另一个函数,然后退出.

javascript pipe continuation-passing

17
推荐指数
1
解决办法
877
查看次数

继续传递类​​型的样式表示

假设我们有一个单子,通过定义return,(>>=)以及一套法律.有一种数据类型

newtype C m a = C { unC ? forall r. (a ? m r) ? m r }
Run Code Online (Sandbox Code Playgroud)

也称为密度.C m a ? m a鉴于这m是一个Monad,即我们可以编写两个函数to ? Monad m ? m a ? C m afrom ? Monad m ? C m a ? m a

to ? Monad m ? m a ? C m a
to t = C $ \f ? t …
Run Code Online (Sandbox Code Playgroud)

continuations haskell continuation-passing

15
推荐指数
1
解决办法
922
查看次数

可以为continuation monad变换器提供一些带有一些和很多的替代实例吗?

我们可以将continuation monad变换器定义为

data Cont r m a = Cont {run :: (a -> m r) -> m r}
Run Code Online (Sandbox Code Playgroud)

Cont r m如果mAlternativevia 的成员,我们可以给出Alternative实例

empty = Cont $ \f -> empty
ca <|> cb = Cont $ \f -> run ca f <|> run cb f
Run Code Online (Sandbox Code Playgroud)

然后允许somemany采用他们的默认方法.我的问题是,我们可以定义somemany在以下方面msomemany,而不是默认的定义是什么?显而易见的选择

some ca = Cont $ \f -> some $ run ca f
many ca = Cont …
Run Code Online (Sandbox Code Playgroud)

continuations haskell typeclass applicative continuation-passing

15
推荐指数
1
解决办法
474
查看次数

解释The Little Schemer第137页的续例

有问题的代码是这样的:

(define multirember&co
  (lambda (a lat col)
    (cond
     ((null? lat)
      (col (quote ()) (quote ())))
     ((eq? (car lat) a)
      (multirember&co a
                      (cdr lat)
                      (lambda (newlat seen)
                        (col newlat
                             (cons (car lat) seen)))))
     (else
      (multirember&co a
                      (cdr lat)
                      (lambda (newlat seen)
                        (col (cons (car lat) newlat)
                             seen))))))
Run Code Online (Sandbox Code Playgroud)

我整天都在盯着这个,但我似乎无法理解它.当您重复使用要重新定义的函数时,col但在示例中它们似乎使用了原始定义.为什么不改变呢.你怎么能在它不复发传递的参数newlatseen.

很难解释我的问题,因为我似乎只是错过了一块.如果有人能比书更明确地介绍一下,我可能会理解它是如何运作的.

recursion lambda scheme the-little-schemer continuation-passing

14
推荐指数
4
解决办法
1870
查看次数

Little Schemer evens-only*&co

我很难理解evens-only*&co第145页的The Little Schemer的例子.

这是代码:

(define evens-only*&co
 (lambda (l col)
   (cond
    ((null? l)
     (col '() 1 0))
    ((atom? (car l))
     (cond
      ((even? (car l))
       (evens-only*&co (cdr l)
                    (lambda (newl product sum)
                      (col (cons (car l) newl)
                           (opx (car l) product)
                           sum))))
      (else
       (evens-only*&co (cdr l)
                    (lambda (newl product sum)
                      (col newl product (op+ (car l) sum)))))))
    (else
     (evens-only*&co (car l)
                  (lambda (newl product sum)
                    (evens-only*&co (cdr l)
                                    (lambda (dnewl dproduct dsum)
                                      (col (cons newl dnewl)
                                           (opx product dproduct)
                                           (op+ …
Run Code Online (Sandbox Code Playgroud)

recursion lambda scheme the-little-schemer continuation-passing

13
推荐指数
1
解决办法
960
查看次数