这是一些代码,以“直接样式”确定列表在 n+1 比较中是否为回文
pal_d1 :: Eq a => [a] -> Bool
pal_d1 l = let (r,_) = walk l l in r
where walk l [] = (True,l)
walk l (_:[]) = (True,tail l)
walk (x:l) (_:_:xs) = let (r, y:ys) = walk l xs
in (r && x == y, ys)
Run Code Online (Sandbox Code Playgroud)
可以在几个例子上进行测试
-- >>> pal_d1 [1,2,1]
-- True
-- >>> pal_d1 [1,2,2,1]
-- True
-- >>> pal_d1 [1,2,3,4,2,1]
-- False
Run Code Online (Sandbox Code Playgroud)
Danvy 在“ There and back again ”中声称没有控制运算符(就在 4.2 之前)没有直接的风格解决方案,因为在下面的 …
首先,我是一个LISP新手.
我想得到的是一个合作的微线程功能.这可以通过协程获得.据我所知,Scheme通过continuation支持协同程序.但是,并非所有Scheme实现都可以延续.如果是这样,我可以添加仅具有LISP原语的延续特征吗?
我在维基百科上遇到了这段代码:
(define (pyth x y k)
(* x x (lambda (x2)
(* y y (lambda (y2)
(+ x2 y2 (lambda (x2py2)
(sqrt x2py2 k))))))))
Run Code Online (Sandbox Code Playgroud)
文章说该代码是另一段代码的Continuation-Passing版本:
(define (pyth x y)
(sqrt (+ (* x x) (* y y))))
Run Code Online (Sandbox Code Playgroud)
但是,我很困惑:这甚至有用吗?你如何将一个数字乘以一个lambda?(* x x (lambda ...))
该冥王星库为Lua中声称能够序列化的Lua协程.我将其解释为'serializeable continuations',这是使异步编程以同步方式可写的重要特性.
例如,工作流可以线性表示,而不是需要命名的入口点
if (ask user is hungry) then
if (not ask user is vegetarian) then
if (ask user if likes_burgers) then
feed_user(burger)
else
tell_user("Picky!")
else
feed_user(salad)
Run Code Online (Sandbox Code Playgroud)
代替
function main()
ask(user is hungry, "hungry_response")
function hungry_response(answer)
if (answer is yes)
ask(user is vegetarian, "vegetarian_response")
function vegetarian_response(answer)
if (answer is yes)
feed_user(salad)
else
ask(user likes burgers, "burgers_response")
function burgers_response(answer)
if (answer is yes) then
feed_user(burger)
else
tell_user("Picky!")
Run Code Online (Sandbox Code Playgroud)
虽然翻译成前一个样式的if语句也不错,但是一旦涉及局部变量,循环,嵌套函数调用等,事情就变得非常复杂.
这是序列化延续变得至关重要的地方.
序列化的延续在JavaFlow,Cocoon(Rhink),Seaside,PLT Scheme,SICS中使用,非常适合处理业务工作流程,医疗诊断和(在我的情况下)文本冒险游戏.
是否有任何Lua和Pluto以这种方式利用其功能的示例(希望是开源!),使用continuation来简化异步环境中的逻辑?
continuations lua serialization asynchronous continuation-passing
假设我必须编写一些GUI代码,如下所示:
widget1.addListener(event1 =>
handle1(event1)
widget2.addListener(event2 =>
handle2(event2)
widget3.addListener(event3 => handle3(event3))
)
)Run Code Online (Sandbox Code Playgroud)
你会如何使用Scala延续以CPS风格编写它?
我想知道是否有一种方法可以实现通用的"memoize"功能(如在函数中作为输入和函数作为输出,作为python的装饰器)能够处理cps样式的函数.
对于正常函数(如"返回结果值,参数仅用于输入!")memoize函数可以像(在javascript中)一样简单
function memoize(fun) {
var cache = {};
return function () {
var args = Array.prototype.slice.call(arguments);
if (args in cache)
return cache[args];
var ret = fun.apply(this, arguments);
cache[args] = ret;
return ret;
};
}
Run Code Online (Sandbox Code Playgroud)
但是我的简单memoize函数无法记忆cps风格的函数,因为我需要再次"评估"类型函数的参数,同时知道要传递给它们的参数.
例如,给定功能
function cps(param, next) {
var ret = param + 1;
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
Run Code Online (Sandbox Code Playgroud)
也许我可以发现这next是一个函数,但它的签名(好吧......也许,但它很棘手),绝对不是函数中使用的参数!
有人能告诉我,我错了吗?:d
我有兴趣能够记住六个cps风格的函数,我不想搞乱在每个函数中插入"缓存"的逻辑.
我有一些代码来评估原始程序.程序是一个语句列表(表达式,块,返回语句).评估结果是最后评估的表达式.评估员也应妥善处理return陈述(即首次出现后停止评估return).
为了实现这个逻辑,我传递了特殊的回调函数(NextStep),它在当前语句之后进行下一个评估步骤.处理return语句时我不调用下一步:
data Statement =
Expr Int
| Block [Statement]
| Return Int
deriving (Show, Eq)
data Value =
Undefined
| Value Int
deriving (Show, Eq)
type NextStep = Value -> Value
evalStmt :: Statement -> NextStep -> Value
evalStmt (Expr val) next =
let res = Value val
in next res
evalStmt (Block stmts) next = evalBlock stmts next
evalStmt (Return val) next = Value val
evalBlock :: [Statement] -> NextStep -> Value …Run Code Online (Sandbox Code Playgroud) 我正在努力练习Haskell的一系列例子.我目前正在学习继续传递,但是我对如何实现像list中的元素的查找索引这样的函数有点困惑:
index 3 [1,2,3] id = 2
Run Code Online (Sandbox Code Playgroud)
像factorial这样的例子有意义,因为除了乘法之外没有真正的数据处理,但是在索引函数的情况下,我需要将我正在查看的元素与我正在寻找的元素进行比较,并且我似乎无法弄清楚如何使用函数参数来做到这一点.
任何帮助都会很棒.
有人可以澄清acc ""在终止基于延续的尾递归函数时的需要,如下例所示:
let rec repeat_cont i s acc =
if i = 0 then acc ""
else repeat_cont (i-1) s (fun x -> acc(s + x))
repeat_cont 4 "xo" id
val it : string = "abababab"
Run Code Online (Sandbox Code Playgroud)
如果结果是一个列表,它会是acc [],和acc 0为整数.
我最近一直在写很多 C 代码,我遇到了一个类似于我在 Go 中遇到的问题,我有很多代码看起来像这样:
if (foo() != 0) {
return -1;
}
bar();
Run Code Online (Sandbox Code Playgroud)
这类似于if err != nil我在 Golang 中看到的常量检查。我想我想出了一个有趣的模式来处理这些容易出错的序列。我受到函数式语言的启发,这些语言具有andThen将可能成功也可能不成功的计算链接在一起的序列。我尝试实现一个简单的回调设置,但我意识到这在没有 lambda 的 C 中几乎是不可能的,即使有它们也会是回调地狱。然后我考虑使用跳转,我意识到可能有一个很好的方法来做到这一点。有趣的部分在下面。如果不使用这种模式,将会有大量的if (Buffer_strcpy(...) != 0)检查或一团糟的回调地狱。
switch (setjmp(reference)) {
case -1:
// error branch
buffer->offset = offset;
Continuation_error(continuation, NULL);
case 0:
// action 0
Buffer_strcpy(buffer, "(", andThenContinuation);
case 1:
// action 1 (only called if action 0 succeeds)
Node_toString(binaryNode->left, buffer, andThenContinuation);
case 2:
Buffer_strcpy(buffer, " ", andThenContinuation);
case 3:
Node_toString(binaryNode->right, buffer, andThenContinuation);
case …Run Code Online (Sandbox Code Playgroud) haskell ×3
scheme ×2
asynchronous ×1
c ×1
callcc ×1
coroutine ×1
f# ×1
javascript ×1
lisp ×1
lua ×1
memoization ×1
recursion ×1
scala ×1