[Camllist] Is arrow programming impossible in ocaml?
[
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:  20031015 (02:20) 
From:  Jacques Garrigue <garrigue@k...> 
Subject:  Re: [Camllist] Is arrow programming impossible in ocaml? 
From: Nick Name <nick.name@inwind.it> > Here it is: > > module type ARROW = > sig > type ('a,'b) t > > val arr : ('a > 'b) > ('a,'b) t > val (>>>) : ('a,'b) t > ('b,'c) t > ('a,'c) t > val (&&&) : ('a,'b) t > ('a,'c) t > ('a,('b * 'c)) t > end [...] > (* now in the toplevel > > # let t = time >>> time;; > val t : ('_a, float) Var.Time.t = <abstr> *) > > Well, that '_a is exactly what I wish to avoid; I see. > I had this suggestion privately (with simplified type declarations): > > # type ('a,'b) sf = Arr of ('a * float > 'b);; > type ('a, 'b) sf = Arr of ('a * float > 'b) > # let (>>>) f1 f2 = match f1(),f2() with (Arr f1),(Arr f2) > Arr (fun > (a,s) > f2 (f1(a,s),s));; > val ( >>> ) : (unit > ('a, 'b) sf) > (unit > ('b, 'c) sf) > ('a, 'c) > sf = > <fun> > # let time () = Arr (fun (_,t) > t);; > val time : unit > ('a, float) sf = <fun> > # let t () = time >>> time;; > val t : unit > ('a, float) sf = <fun> > > and yet I don't know if it's satisfactory. What would be the problem? This is just about delaying the arrow construction, to make sure that no sideeffect may occur. > however I realize that this > is a general problem with caml view of polymorphism, probably driven by > typeinference decidability issues; in fact I can't write a polymorphic > compose operator in general, because I will get exactly the same > problems. This has nothing to do with decidability at all! Again, this is the value restriction, which solves a problem with soundness in presence of sideeffects, and this is a FAQ. And you can perfectly define a polymorphic compose operator. # let compose f g x = f (g x);; val compose : ('a > 'b) > ('c > 'a) > 'c > 'b = <fun> The only difficulty is that to create polymorphic functions with this operator you must apply etaexpansion. # let swap (x,y) = (y,x);; val swap : 'a * 'b > 'b * 'a = <fun> # fun p > compose swap swap p;;  : 'a * 'b > 'a * 'b = <fun> By the way, if you are ready to break abstraction (which in your case doesn't seem essential), you can build a t with the right polymorphic type: # let t = T(fun s > let T a = time >>> time in a s);; val t : ('a, float) Var.Time.t = ... Not very clean, but you can replace time >>> time by any polymorphic expression. It can be made a bit simpler by using a record instead of a sum: # let t = {f=fun s > (time >>> time).f s};; Jacques Garrigue  To unsubscribe, mail camllistrequest@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/camlbugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners