[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2009-10-16 (15:15) |
From: | Till Varoquaux <till@p...> |
Subject: | Re: [Caml-list] How to add () to function parameters |
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.Crueger@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 >