I am pretty sure this is not related to references, but to let-rec. Try: let rec f x = x and g y = f y + 1;; you will see that the type inferred is: val f : int -> int val g : int -> int Now try: let f x = x and g y = f y + 1;; this time: val f : 'a -> 'a val g : int -> int You may still be wondering why, of course. The basic answer (I hope I am not too rusty in this) is that type inference for polymorphic let-rec is not decidable (you have to solve a semi-unification problem). Hence, the "solution" is not to abstract type variables until all type inference for all let-rec-and clauses have been analyzed. So: let rec f x = x and g y = f y + 1 and h z = not (h z);; does not type check at all, but again: let f x = x and g y = f y + 1 and h z = not (h z);; does work. Nikolaj From: Chris Hecker [mailto:checker@d6.com] Sent: Thu 2/6/2003 5:31 PM To: caml-list@inria.fr Subject: [Caml-list] streams and value restriction I assume I'm running into the polymorphism restriction thing here, but I'm not sure why (I kind of understand it when references are in play, but this is baffling me). Here's a simple version of some stream parser code. I'd like parse_opt_comma_list to be polymorphic so I can use it to parse lists of any of my values. It works fine as a separate let rec, but if I put it in the overall let rec of the main parser (with and) it won't generalize and gets tagged as string-only since that's the first way it's used. Can somebody explain why this is a problem? Sorry for being dense. Thanks, Chris type t = Int of int | String of string (* this works: *) let rec parse_opt_comma_list parse list = parser [< 'Genlex.Kwd ","; a = parse ; optlist = parse_opt_comma_list parse (a::list) >] -> optlist | [< >] -> list let rec parse_values = parser [< 'Genlex.String s; optlist = parse_opt_comma_list (parser [< 'Genlex.String s >] -> s) [] >] -> (String s) :: List.map (fun s -> String s) optlist | [< 'Genlex.Int i; optlist = parse_opt_comma_list (parser [< 'Genlex.Int i >] -> i) [] >] -> (Int i) :: List.map (fun i -> Int i) optlist (* this doesn't: *) let rec parse_values = parser [< 'Genlex.String s; optlist = parse_opt_comma_list (parser [< 'Genlex.String s >] -> s) [] >] -> (String s) :: List.map (fun s -> String s) optlist | [< 'Genlex.Int i; optlist = parse_opt_comma_list (parser [< 'Genlex.Int i >] -> i) [] >] -> (Int i) :: List.map (fun i -> Int i) optlist and parse_opt_comma_list parse list = parser [< 'Genlex.Kwd ","; a = parse ; optlist = parse_opt_comma_list parse (a::list) >] -> optlist | [< >] -> list ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners