Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] monomorphic restriction or typing/scanf bug?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Pierre Weis <pierre.weis@i...>
Subject: Re: [Caml-list] monomorphic restriction or typing/scanf bug?
> The "scan" function in the code below works if it's at global scope,
> but not if it's defined inside the test2 function.  Is this a bug or a
> typing restriction?  I assume the latter (and that I could have boiled
> this example to one of the ones in the FAQ?), but I don't understand
> these kinds of polymorphism typing issues.
> 
> Chris
> 
> 
> type t =
>     Foo of int
>   | Bar of int * int 
> 
> exception FB of t
> 
> 
> (* works *)
> let scan s (fmt : ('a, Scanf.Scanning.scanbuf, 'b) format) f =
>   try
>     raise (FB (Scanf.sscanf s fmt f))
>   with
>     End_of_file | Scanf.Scan_failure _ -> ()
> 
> let test () =
>   let line = "Foo 1" in
>   try
>     scan line "Foo %d" (fun i -> Foo i);
>     scan line "Bar %d %d" (fun i j -> Bar (i,j));
>     failwith "bad line"
>   with
>     FB t -> t
> 
> (* doesn't work *)
> let test2 () =
>   let line = "Foo 1" in
>   let scan s (fmt : ('a, Scanf.Scanning.scanbuf, 'b) format) f =
>     try
>       raise (FB (Scanf.sscanf s fmt f));
>       ()
>     with
>       End_of_file | Scanf.Scan_failure _ -> ()
>   in
>   try
>     scan line "Foo %d" (fun i -> Foo i);
>     scan line "Bar %d %d" (fun i j -> Bar (i,j));
>     failwith "bad line"
>   with
>     FB t -> t
> 
> -------------------
> 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

This is unrelated to Scanf (apart from the fact that sscanf is
polymorphic).

This is not a bug, this is not a typing restriction, this is an ugly
semantics of type constraints.

The problem is that type variables in type constraints are shared (are
not generalized whatsoever) in a whole definition. Hence, the 'a and
'b in your format specification accumulate incompatible type
constraints (type instance unifications), hence the typing error
reported by the compiler.

On the other hand, when the scan function is global, 'a and 'b are
generalized at the hand of the definition as usual (since their is no
use of scan, hence no instanctiation of 'a nor 'b). Hence the global
definition does not behave teh same as the local one.

To give a simpler example, consider this simple (working) code snippet:

# let test () =
    let f x = x in
    f 1; f "1";;
Warning: this expression should have type unit.
val test : unit -> string = <fun>

Now, consider I add a single (and useless) type constraint on the x
parameter of f, just stating that it should have a type:

# let test () =
    let f (x : 'a) = x in
    f 1; f "1"
  ;;
Warning: this expression should have type unit.
This expression has type string but is here used with type int

The phrase it rejected since the type ('a) of the parameter (x) of f
has been instantiated once with int, and then further instantiation to
string fails (the warning emitted by the compiler clearly states that
"f 1" was properly type-checked).

Thnaks for the interesting example, that could help us to revised the
semantics of type constraints in Caml, still having in mind that
global and local definition should always behave the same.

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/


-------------------
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