C#的async/await与更一般的结构(例如F#的工作流或单子)有何关联?

10 浏览
0 Comments

C#的async/await与更一般的结构(例如F#的工作流或单子)有何关联?

C#语言设计在历史上一直致力于解决特定问题,而不是寻找解决潜在通用问题的方法:例如,参考http://blogs.msdn.com/b/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx中的"IEnumerable vs. coroutines"可以看出:

我们本可以设计得更加通用。我们的迭代器块可以被看作是一种弱协程。我们本可以选择实现完整的协程,将迭代器块作为协程的一种特殊情况。当然,协程本身也不如一级延续那样通用;我们可以实现延续,再用延续实现协程,用协程实现迭代器。

或者参考http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx中的SelectMany作为(某种)Monad的替代品:

C#类型系统不足以创建一个通用的monad抽象,这是创建扩展方法和"query pattern"的主要动机。

我不想问为什么会这样(已经有很多好的答案了,特别是在Eric的博客中,这些设计决策都可能适用:从性能到增加编译器和程序员的复杂性)。

我想要理解的是async/await关键字与哪个"通用构造"相关(我最好的猜测是延续monad - 毕竟,F#异步是使用工作流实现的,根据我理解是一个延续monad),以及它们与之的关系(它们有什么不同?有什么缺失?如果有,为什么会有这样的差距?)

我希望得到类似于我提供的Eric Lippert文章的回答,但与IEnumerable/yield有关的问题不同,而是与async/await有关的问题。

0