Oh, and I nearly forgot: In practice you shouldn't really have that many functions taking more than 5 unlabeled arguments lying around so I would bite the bullet and define cps1 through 5 the straightforward way....
Till On Fri, Oct 16, 2009 at 11:15 AM, Till Varoquaux <t...@pps.jussieu.fr> wrote: > Well I can basically see two solutions (plus countless complications > that I won't go into.) > > We want to define a function > > val cps3: f:('a -> 'b -> 'c -> 'd) -> ('d -> 'e) -> 'a -> 'b -> 'c -> 'e = > > that takes a three argument function a returns the same function in CPS style. > > The functional unparsing/danvy way [1]: > >> let (++) f g = fun x -> f (g x) >> let i k f arg = k (f arg) >> let cps ty ~f k = ty k f >> let cps3 ~f = cps (i++i++i) ~f > > brute force style: > >> let e acc ~f cont = acc cont f >> let i = fun acc g -> g (fun cont v arg -> acc cont (v arg)) >> let cps = fun z -> >> let acc = (fun cont x -> cont x) in >> z acc >> let cps3 ~f = cps i i i e ~f > > The first style is an acquired taste quite the same way that monad > are. With some getting use to and abstracting your types in a sensible > way you can enclose things quite nicely and define elegant > printf/scanf kind of functions. > > I strongly discourage you to use the second style. It is a very > reworked mlton.fold [2] style solution. mlton's fold is a lot more > esoteric and leads to types that I have never been able to abstract > properly. > > Till > > [1] http://www.brics.dk/RS/98/12/ > [2] http://mlton.org/Fold > > On Wed, Oct 14, 2009 at 6:44 AM, Till Crueger <till.crue...@gmx.net> wrote: >> Hi, >> >> I am looking for a way to add a unit parameter to a function that takes an >> arbitrary number of parameters. If the number of parameters is known this is >> fairly easy and I can just do: >> >> let lift1 f a = >> fun () -> >> f a;; >> >> let lift2 f a b = >> fun () -> >> f a b;; >> >> (all these create one closure per lifting) >> etc... >> >> However it is a bit of a hassle to have to code each of these lifts... So >> what I am looking for is a way to extend this pattern to all numbers. So far >> I got to the point that I can do the following: >> >> let lift_once f a = >> fun () -> >> f a;; >> >> let lift_more f a = >> fun () -> >> f () a;; >> >> So for a function f taking two parameters a and b I can do >> >> lift_more (lift_once f a) b >> (two closures created) >> >> and for a function taking the parameters a, b and c I can do >> >> lift_more (lift_more (lift_once f a) b) c >> (three closures created) >> >> to get the lifted functions. >> >> However this solution gets quite ugly with all the parentheses. Also there >> are a lot of closures being produced and evaluated for any single lifting. I >> had a look at the Jane Street blog post about variable argument functions >> (http://ocaml.janestcapital.com/?q=node/22), which seems to do similar >> things. However I have never been really good with CPS, so I don't know if >> those techniques can be applied to this problem. >> >> Is there any way to do this, which does not get this ugly. Also the >> resulting lifted function should not contain too many closures. >> >> Thanks for your help, >> Till >> >> _______________________________________________ >> Caml-list mailing list. Subscription management: >> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list >> Archives: http://caml.inria.fr >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> Bug reports: http://caml.inria.fr/bin/caml-bugs >> > _______________________________________________ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs