Browse thread
Re: [Caml-list] let rec and polymorphic functions
- David Allsopp
[
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: | -- (:) |
| From: | David Allsopp <dra-news@m...> |
| Subject: | Re: [Caml-list] let rec and polymorphic functions |
> There are many problems with this. Google for ad-hoc polymorphism, > polymorphic recursion and generic printing. > > On Wednesday 27 June 2007 09:40:31 David Allsopp wrote: > > out "TEST"; > > val out : string -> unit > > > out "%d" 0; > > val out : format -> int -> unit The type-checker doesn't see that surely? Surely on that expression it sees out : string -> int -> unit?? Note that changing the sequence to out "%b" true; out "%d" 0; and removing the out "TEST" still causes problems - although O'Caml manages to infer the [format4] first argument for [out], it fixes the first parameter of the [format4] as being [bool -> unit] and so prevents [out] from being used with anything other than a single "%b" argument and hence gives a type error on the next application. > As printf is ad-hoc polymorphic, you must supply the format specifier > immediately and OCaml will generate a custom printer for you. OCaml does > not use run-time types so you cannot have a generic print function: you > must specific print functions for each of your (possibly higher-order) > types. Yes, except that what's odd to me is that the type-checker doesn't behave as the manual says it ought to with [let rec]. BUT... > Also, recursive calls ossify the function to a monomorphic type, so you > cannot do polymorphic recursion in OCaml. There are workaround using > recursive modules or objects but I don't think this is what you want here. That does explain it - which I didn't know. Consider this which is also broken (and simpler because it has nothing to do with the ad-hoc polymorphism of printf) let rec id x = x and _ = id 0 in id (); (* *** *) id 1;; Gives a type error for *** because id is already inferred as int -> int because of the monomorphic nature of the recursive definition. This is over-guarded but I never got an answer on a previous post as to why. The equivalent SML does type polymorphically: let fun id x = x val _ = id 0 in id (); id 1 end; Incidentally, it's lucky that this is polymorphic in SML because all function definitions are recursive IIRC. But no-one posted an explanation as to why there's this difference in the let construct between the two flavours of ML :( David