continuation-passing

why do continuations avoid stackoverflow?

耗尽温柔 提交于 2019-12-22 03:52:54
问题 I've been trying to understand continuations / CPS and from what I can gather it builds up a delayed computation, once we get to the end of the list we invoke the final computation. What I don't understand is why CPS prevents stackoverflow when it seems analogous to building up a nested function as per the naive approach in Example 1. Sorry for the long post but tried to show the idea (and possibly where it goes wrong) from basics: So: let list1 = [1;2;3] Example 1: "Naive approach" let rec

Attempting to use continuation passing style to avoid stack overflow with minimax algorithm

白昼怎懂夜的黑 提交于 2019-12-21 17:48:09
问题 Summary of my objective: Figure out how to use continuation-passing style to avoid a stack overflow when using an algorithm I believe cannot be made tail-recursive. Alternatively, find a way to make the function tail-recursive. Details: I am new to F# (and functional programming in general) and I am attempting to implement the minimax algorithm with alpha-beta pruning. This is an algorithm used to determine the best possible move for a two-player game. The pseudocode for the algorithm can be

Why does the OCaml std lib have so many non-tail-recursive functions?

北城以北 提交于 2019-12-21 07:32:38
问题 I have been rewriting many OCaml standard library functions to be tail-recursive lately. Given that this has entailed straight-forward CPS transformation, I am left puzzling over why the default versions are not written this way. As an example, in the standard library, map is defined as: let rec map f = function [] -> [] | a::l -> let r = f a in r :: map f l I have rewritten it to be: let map f l = let rec aux l k = match l with [] -> k [] | a::l -> aux l (fun rest -> k (f a :: rest)) in aux

How to implement a stack-safe chainRec operator for the continuation monad?

耗尽温柔 提交于 2019-12-17 17:05:46
问题 I am currently experimenting with the continuation monad. Cont is actually useful in Javascript, because it abstracts from the callback pattern. When we deal with monadic recursion, there is always the risk of a stack overflow, because the recursive call isn't in tail position: const chain = g => f => k => g(x => f(x) (k)); const of = x => k => k(x); const id = x => x; const inc = x => x + 1; const repeat = n => f => x => n === 0 ? of(x) : chain(of(f(x))) (repeat(n - 1) (f)); console.log(

Can the CPS-styled `call/cc` be written in terms of a hypothetical non-CPS-styled `cc'`?

牧云@^-^@ 提交于 2019-12-10 18:13:17
问题 In a language which supports continuation, e.g. Scheme, Ruby, and Haskell, suppose there is a function cc' which takes no argument and return the current continuation, so that the caller that obtains a continuation by calling cc' can then invoke the continuation anywhere and as often as it likes. cc' can be written in terms of the CPS-styled call/cc , by passing an identity function as an argument to call/cc . Conversely, can the CPS-styled call/cc be written in terms of the non-CPS-styled cc

Is there a way to chain functions like withCString?

别说谁变了你拦得住时间么 提交于 2019-12-09 14:50:06
问题 Is there a way to chain functions like withCString ? By that I mean any function that looks something like f :: Foo -> (CFoo -> IO a) -> IO a . For example, lets say there is a function cFunc :: CString -> CFoo -> CBar -> IO () Usualy, I would do something like: haskellFunc string foo bar = withCString string $ \ cString -> withCFoo foo $ \ cFoo -> withCBar bar $ \ cBar -> cFunc cString cFoo cBar But i would like to do something like: haskellFunc = (withCString |.| withCFoo |.| withCBar)

How do collector functions work in Scheme?

末鹿安然 提交于 2019-12-08 17:48:07
问题 I am having trouble understanding the use of collector functions in Scheme. I am using the book "The Little Schemer" (by Daniel P. Friedman and Matthias Felleisen). A comprehensive example with some explanation would help me massively. An example of a function using a collector function is the following snippet: (define identity (lambda (l col) (cond ((null? l) (col '())) (else (identity (cdr l) (lambda (newl) (col (cons (car l) newl)))))))) ... with an example call being (identity '(a b c)

Continuation-Passing Style in Scheme?

梦想与她 提交于 2019-12-07 05:34:09
问题 I ran into this code on Wikipedia: (define (pyth x y k) (* x x (lambda (x2) (* y y (lambda (y2) (+ x2 y2 (lambda (x2py2) (sqrt x2py2 k)))))))) The article says that that code is the Continuation-Passing version of another piece of code: (define (pyth x y) (sqrt (+ (* x x) (* y y)))) However, I'm quite confused: How does that even work? How do you multiply a number by a lambda here? (* x x (lambda ...)) 回答1: In the Wikipedia example, * doesn't mean the same thing as * in the conventional

Changing a function into CPS style

南楼画角 提交于 2019-12-06 08:33:19
问题 We were asked to write a procedure that when given a list it will replace the first occurrence of a given element and only the first, but the catch is to write in CPS style. We are unable to turn it to CPS style written procedure that is given a success-cont and fail-cont.. If anyone is willing to give it a try we will really appreciate it :] The procedure we have (graciously provided by answers here): (define (replace-one list old new) (cond ((pair? list) (let ((next (replace-one (car list)

heap usage for CPS vs non-CPS parsers in Haskell's parsec

主宰稳场 提交于 2019-12-06 04:40:31
I'm trying to write the following parser using parsec : manyLength :: forall s u m a. Monad m => ParsecT s u m a -> ParsecT s u m Int manyLength p = go 0 where go :: Int -> ParsecT s u m Int go !i = (p *> go (i + 1)) <|> pure i This is like the many function, but instead of returning [a] , it returns the number of times Parser a succeeds. This works, but I can't seem to make it run in constant heap space. This makes sense, since the recursive call to go is not in the tail-call position. If parsec would export the constructor to ParsecT , it would be possible to rewrite manyLength in CPS'ed