- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我来自 OOP、非功能性背景,因此我无法完全可视化有关 continuation passing 的几个在线示例。 。另外,像Scheme这样的函数式语言不需要指定参数类型或返回值,所以我不确定我的想法是否正确。
由于 C# 支持 lambda,我从 Wikipedia 文章中获取了第一个示例,并尝试将其移植到具有强类型的 C#,以了解该模式的应用方式:
// (Scheme)
// direct function
(define (pyth x y)
(sqrt (+ (* x x) (* y y))))
// rewriten with CPS
(define (pyth& x y k)
(*& x x (lambda (x2)
(*& y y (lambda (y2)
(+& x2 y2 (lambda (x2py2)
(sqrt& x2py2 k))))))))
// where *&, +& and sqrt& are defined to
// calculate *, + and sqrt respectively and pass the result to k
(define (*& x y k)
(k (* x y)))
因此,重写 CPS pyth&
C# 版本导致:
// (C#6)
// continuation function signature
delegate double Cont(double a);
// *&, +& and sqrt& functions
static double MulCont(double a, double b, Cont k) => k(a * b);
static double AddCont(double a, double b, Cont k) => k(a + b);
static double SqrtCont(double a, Cont k) => k(Math.Sqrt(a));
// sqrt(x*x + y*y), cps style
static double PythCont(double x, double y, Cont k) =>
MulCont(x, x, x2 =>
MulCont(y, y, y2 =>
AddCont(x2, y2, x2py2 =>
SqrtCont(x2py2, k))));
我可以使用泛型而不是 double
,但签名会更长。无论如何,我不确定的是:
是 Cont
上面的签名正确吗(即 Func<double, double>
)?应该继续fn。接受参数,处理它,然后返回相同类型的值?
当我第一次开始阅读有关延续的内容时,我感觉这个延续函数将在调用堆栈中的每个步骤中被调用,但在上面的示例中,它仅传递给 sqrt&
,并且所有其他调用都会获取 lambda,但这些 lambda 并不真正将中间值“传递”到原始延续。上面函数中的代码基本上类似于 k(Math.Sqrt(x * x + y * y))
,那么这是否意味着我对中间“钩子(Hook)”的假设是错误的?
最佳答案
是的,除非您想对最外层的延续执行任何非数字操作,否则它是正确的。当您的原始表达式涉及更多类型时,您只需要更多“Cont”,例如
(定义(foo x)(if(= x 0)1 0))
在这种情况下,它可能看起来像这样(抱歉,为了简洁,我写在方案中):
(define (foo& x k)
(=& x 0 (lambda (r1)
(if r1 (k 1) (k 0)))))
-- 现在最外面的延续有一个数字(假设是一个 int)作为输入,而提供给“=&”的数字具有 bool->int 类型。
您问的另一件事是 cps 与控制流有何关系。好吧,请注意,在应用性函数语言(如方案)中,您唯一指定的是在应用程序中,您首先评估操作数和运算符,然后将后者应用于前者。以什么顺序评估操作数并不重要——你可以从左到右、从右到左[或者也许以某种疯狂的方式]。但是,如果您不使用纯函数式风格,并且操作数会产生一些副作用,该怎么办?他们可能例如将一些内容打印到标准输出,然后返回一些值。在这种情况下,您希望控制订单。 如果我没记错的话,用 gambit-C 编译的程序从右到左计算参数,而用 gambit 的解释器从左到右解释 - 所以问题确实存在;)。正是这样,cps 可能会拯救你[实际上还有其他方法,但我们现在正在讨论 cps!]。在您发布的方案示例中,强制从左到右评估“+”的参数。您可以轻松更改它:
(define (pyth& x y k)
(*& y y (lambda (y2)
(*& x x (lambda (x2)
(+& x2 y2 (lambda (x2py2)
(sqrt& x2py2 k))))))))
就是这样。
在一些进一步的应用程序中,正如人们在评论中已经说过的那样,转换为 CPS 会将每个应用程序移至尾部位置,因此调用堆栈将被 lambda 替换,此外,如果您对它们进行去功能化,您得到的是数据表示控制流的结构——一种要转换为 C 语言或其他命令式语言的简洁形式。全自动!或者,如果你想实现一些 monad mumbo-jumbo,比如说 Maybe monad,在 CPS 中这很简单,只需在每个 continuation-lambda 前面添加测试接收到的值是否是“Just something” (在这种情况下,完成工作并将结果推送到您的延续),或“Nothing”,在这种情况下,您只需推送 Nothing(到延续 lambda)。当然,而是通过另一个程序或宏,而不是手动,因为这可能很乏味 - cps 最神奇的地方在于,可以很容易地自动转换为 cps。
希望我没有让它变得不必要的复杂。
关于c# - 连续传递风格的中间值和返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38611717/
Textmate 语法(.tmLanguage 文件)有时以 XML 格式表示。 我想转换为更易读的格式(即 JSON 或 YAML)以集成到 VS Code 语法突出显示扩展中。 为了澄清我的意思,
如何通过 pandas 样式隐藏列标签?有一个 hide_index() 方法可以删除索引行,不幸的是 hide_column() 标签会删除整个列(标题和数据)。我只想隐藏标题。谢谢! 最佳答案 s
我正在考虑为一组服务使用 SOA 架构来支持我咨询的业务,以前我们使用数据库集成,其中每个应用程序从共享的 MS SQL 数据库中挑选出它需要的东西并使用它等等。我们有各种与怪物数据库(包括 java
所以我有以下代码,我想知道 Objective-C 中哪种“风格”被认为更好。 选项 1: id temp = [dictionary objectForKey: @"aBooleanValue"];
当创建一个没有类参数的对象时,我很难决定是否应该包含空括号。一个具体的例子:我正在与现有的 Java 代码交互,并创建一个实现名为 EventResponder 的接口(interface)的对象。我
我有一个抽象类Stack和一个扩展它的类:MyStack。我需要为 MyStack 创建一个复制构造函数。只传入 MyStack 对象更好,还是传入任何 Stack 对象更好? public MySt
我正在考虑将那些在函数体中未修改的 Python 函数参数拼写为 ALL_UPPERCASE,向此类 API 的用户发出信号,表明传递的值不会被修改(如果一切都如广告所言,无论如何) )。我不知道这会
我的 build.gradle 文件、staging、stable 和 production 以及默认构建类型 debug 和 release。对于其中的每一个,我都有不同的 AAR 文件,例如,我有
假设我有以下文件: main.cpp 例程.cpp 例程.h 进一步假设 main.cpp 调用了在 routine.cpp 中定义的函数 routine(),但是 routine.cpp 还包含仅由
我对此进行了一些搜索,但实际上我还没有找到 MySQL 中用于创建外键的样式概念是什么 - 在创建表定义中或在 alter 语句中。谢谢。 最佳答案 何时创建外键: 如果在创建表时明确需要外键,则在创
您好,我正在尝试将 Android 应用风格(免费且完整)实现为动态壁纸。在 Eclipse 中,我曾经使用以下代码从我自己的 Android Activity 打开动态壁纸预览: I
我的 Android 应用程序有两种不同的风格,lite 和 pro。在应用程序中,我有一个名为 customFragment.java 的类,它包含在 main 中(不同风格之间没有区别)并且还包含
我有一个包含多个子目录的项目,如下所示: /opt/exampleProject/src ├── __init__.py ├── dir1 │ ├── __init__.py │ ├──
假设我们有类似的东西 int f(int n); .... do{ int a = b; int b = f(a); } 这样说有没有风险 do{ int b = f(b);
是否有风格指导或理由来选择其中一种模式而不是另一种? 最小化上下文管理器下的代码量“感觉”更干净,但我无法指出具体原因。这可能只是偏好,并没有关于此事的官方指导。 1) 里面的所有代码都有上下文。 w
module Hints module Designer def self.message "Hello, World!" end
我正在开发一个具有多种风格的 android 项目。 这很好用,我可以自定义应用程序的元素,例如颜色和字符串资源。 我想让一些风格基于 AppCompat 浅色主题,一些基于 AppCompat 深色
因此,这不起作用,因为 seatsAvailable 是最终的。如何使用更多的 lambda 风格的从头开始的方式来完成我想要完成的事情? final boolean seatsAvailable =
考虑以下代码: cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); sched_setaffinity(0, sizeof(cpuset
从历史上看,我总是这样编写我的异常处理代码: Cursor cursor = null; try { cursor = db.openCursor(null, null
我是一名优秀的程序员,十分优秀!