* bizarre type @ 2005-06-30 15:48 Julien Verlaguet 2005-06-30 16:49 ` [Caml-list] " Andreas Rossberg 0 siblings, 1 reply; 11+ messages in thread From: Julien Verlaguet @ 2005-06-30 15:48 UTC (permalink / raw) To: caml-list I would like to know if the following behavior is normal : type 'a t=string ;; # let g (x : 'a t) (y : 'a)=();; val g : 'a t -> 'a -> unit = <fun> # g ("hello" : int t);; - : '_a -> unit = <fun> I was expecting: (int -> unit). J ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 15:48 bizarre type Julien Verlaguet @ 2005-06-30 16:49 ` Andreas Rossberg 2005-06-30 16:58 ` Julien Verlaguet 2005-06-30 18:30 ` Julien Verlaguet 0 siblings, 2 replies; 11+ messages in thread From: Andreas Rossberg @ 2005-06-30 16:49 UTC (permalink / raw) To: caml-list Julien Verlaguet wrote: > I would like to know if the following behavior is normal : > > type 'a t=string ;; > > # let g (x : 'a t) (y : 'a)=();; > val g : 'a t -> 'a -> unit = <fun> > > # g ("hello" : int t);; > - : '_a -> unit = <fun> > > I was expecting: (int -> unit). Since int t = string = '_a t or more generally, x t = y t for any x and y, your type annotation does not induce anything about the instantiation of g's variable 'a. The following is perfectly legal: g ("hello" : int t) true The compiler just infers the most general type. Cheers, - Andreas -- Andreas Rossberg, rossberg@ps.uni-sb.de Let's get rid of those possible thingies! -- TB ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 16:49 ` [Caml-list] " Andreas Rossberg @ 2005-06-30 16:58 ` Julien Verlaguet 2005-06-30 17:16 ` Stephane Glondu 2005-06-30 17:24 ` Andreas Rossberg 2005-06-30 18:30 ` Julien Verlaguet 1 sibling, 2 replies; 11+ messages in thread From: Julien Verlaguet @ 2005-06-30 16:58 UTC (permalink / raw) To: Andreas Rossberg; +Cc: caml-list > The compiler just infers the most general type. Ok. But if I write : # type 'a t;; type 'a t # let g (x : 'a t list) (y : 'a)=();; val g : 'a t list -> 'a -> unit = <fun> # g ([] : int t list);; - : int -> unit = <fun> If I understood well what you just said the inferred type should be : '_a -> unit Or is there something I missed there ? J ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 16:58 ` Julien Verlaguet @ 2005-06-30 17:16 ` Stephane Glondu 2005-06-30 17:24 ` Andreas Rossberg 1 sibling, 0 replies; 11+ messages in thread From: Stephane Glondu @ 2005-06-30 17:16 UTC (permalink / raw) To: caml-list On Thursday 30 June 2005 09:58, Julien Verlaguet wrote: > # g ([] : int t list);; > - : int -> unit = <fun> I still get '_a -> unit here (I'm using v3.08.3)... However, I also believe that in both cases, it should be int -> unit. Stephane Glondu. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 16:58 ` Julien Verlaguet 2005-06-30 17:16 ` Stephane Glondu @ 2005-06-30 17:24 ` Andreas Rossberg 1 sibling, 0 replies; 11+ messages in thread From: Andreas Rossberg @ 2005-06-30 17:24 UTC (permalink / raw) To: caml-list Julien Verlaguet wrote: > > But if I write : > > # type 'a t;; > type 'a t > > # let g (x : 'a t list) (y : 'a)=();; > val g : 'a t list -> 'a -> unit = <fun> > > # g ([] : int t list);; > - : int -> unit = <fun> > > If I understood well what you just said the inferred type should be : > > '_a -> unit In this case, t is fully abstract. So int t is only equivalent to itself, and not to arbitrary x t. -- Andreas Rossberg, rossberg@ps.uni-sb.de Let's get rid of those possible thingies! -- TB ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 16:49 ` [Caml-list] " Andreas Rossberg 2005-06-30 16:58 ` Julien Verlaguet @ 2005-06-30 18:30 ` Julien Verlaguet 2005-06-30 19:37 ` Andreas Rossberg 1 sibling, 1 reply; 11+ messages in thread From: Julien Verlaguet @ 2005-06-30 18:30 UTC (permalink / raw) To: Andreas Rossberg; +Cc: caml-list > for any x and y, your type annotation does not induce anything about the > instantiation of g's variable 'a. The following is perfectly legal: > > g ("hello" : int t) true > > The compiler just infers the most general type. two things : first # type 'a t=string;; type 'a t = string # let g (x : 'a) (y : 'a t)=();; val g : 'a -> 'a t -> unit = <fun> # g 3;; - : int t -> unit = <fun> here we should have int t=string='_a t ... second : I strongly disaggree with the fact that the compiler infered the most general type in this case. Because I specified it. when you write (let f=fun (x : 'a) (y : 'a) -> (x,y)), you force the type of x and y to be equal. It would be a problem if one could write (f true 3). J PS : The behavior with abstract types is the one expected and my example in the previous mail was irrelevant (sorry about that). ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 18:30 ` Julien Verlaguet @ 2005-06-30 19:37 ` Andreas Rossberg 2005-06-30 21:42 ` Julien Verlaguet 0 siblings, 1 reply; 11+ messages in thread From: Andreas Rossberg @ 2005-06-30 19:37 UTC (permalink / raw) To: caml-list From: "Julien Verlaguet" <Julien.Verlaguet@pps.jussieu.fr> > > # type 'a t=string;; > type 'a t = string > # let g (x : 'a) (y : 'a t)=();; > val g : 'a -> 'a t -> unit = <fun> > # g 3;; > - : int t -> unit = <fun> > > here we should have int t=string='_a t ... Well, since '_a t = int t the compiler can freely choose either for printing. Or bool t, for that matter. > I strongly disaggree with the fact that the compiler infered the most > general type in this case. > > Because I specified it. > > when you write (let f=fun (x : 'a) (y : 'a) -> (x,y)), you force the type > of x > and y to be equal. Yes, but that's not what you did in the other example. You wrote (x : 'a t) - and because of the way t was defined this was as good as writing (x : string) and hence did not induce any additional constraint. Cheers, - Andreas ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 19:37 ` Andreas Rossberg @ 2005-06-30 21:42 ` Julien Verlaguet 2005-06-30 23:57 ` Jacques Garrigue 2005-07-03 11:42 ` Damien Doligez 0 siblings, 2 replies; 11+ messages in thread From: Julien Verlaguet @ 2005-06-30 21:42 UTC (permalink / raw) To: Andreas Rossberg; +Cc: caml-list > Well, since '_a t = int t the compiler can freely choose either for > printing. Or bool t, for that matter. agreed. > Yes, but that's not what you did in the other example. You wrote (x : 'a > t) - and because of the way t was defined this was as good as writing (x : > string) and hence did not induce any additional constraint. Ok, I have to aggree. In fact it prevents me from writting this : type 'a marshalled=string let make (x : 'a)=(Marshal.to_string x [] : 'a marshalled);; And then do all type of operations in a type safe way on strings. I have to aggree though that I wrote 'a t=string and therefore one should be able to exchange them. The only tiny thing that disturbs me is that in my previous example : let g (x : 'a t) (y : 'a) the type of y depends on the 'a present in 'a t. It is odd. But I have to admit it's correct. Thanks for your help. J ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 21:42 ` Julien Verlaguet @ 2005-06-30 23:57 ` Jacques Garrigue 2005-07-03 11:42 ` Damien Doligez 1 sibling, 0 replies; 11+ messages in thread From: Jacques Garrigue @ 2005-06-30 23:57 UTC (permalink / raw) To: Julien.Verlaguet; +Cc: caml-list From: Julien Verlaguet <Julien.Verlaguet@pps.jussieu.fr> > > > Well, since '_a t = int t the compiler can freely choose either for > > printing. Or bool t, for that matter. > > agreed. Nice to see that everybody agrees that the current behaviour is reasonable :-) And thanks to Andreas for explaining things so well. Yet, these useless parameters are a rather weak part of the compiler, so there may be some bugs left there. I.e. it is hard to guarantee that "a t" will alway be equivalent to "b t" for any use, while they should be so in the intended semantics. Bugs report are welcome. In general, I would suggest avoiding non-abstract phantom types, as they are useless... except when you're going to abstract them at the next module boundary. > In fact it prevents me from writting this : > > type 'a marshalled=string > > let make (x : 'a)=(Marshal.to_string x [] : 'a marshalled);; > > And then do all type of operations in a type safe way on strings. What you want seems to be the Graal: a type that is more than a string, but can be implicitly coerced to one. Of course the opposite direction would not be allowed. A standard way to do that is to make [marshalled] abstract, and provide a function [to_string] when you need to recover the string. In ocaml 3.09, you will have another possibility: using a private type for that, with the extra advantage of having pattern-matching (this doesn't work with private types in 3.08, as they are not handled as abstract.) But not yet the Graal, which requires to combine implicit subtyping with type inference in a non-trivial way... > The only tiny thing that disturbs me is that in my previous example : > > let g (x : 'a t) (y : 'a) > > the type of y depends on the 'a present in 'a t. > It is odd. But I have to admit it's correct. The point here is that ['a t] is not the type of [x] itself, but a type that can be unified with it. And useless parameters are discarded during unification. At a more theoretical level, ['a t] is only required to be equivalent to the type of [x], not identical. Jacques Garrigue ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-06-30 21:42 ` Julien Verlaguet 2005-06-30 23:57 ` Jacques Garrigue @ 2005-07-03 11:42 ` Damien Doligez 2005-07-03 12:37 ` Jacques Garrigue 1 sibling, 1 reply; 11+ messages in thread From: Damien Doligez @ 2005-07-03 11:42 UTC (permalink / raw) To: caml-list On Jun 30, 2005, at 23:42, Julien Verlaguet wrote: > In fact it prevents me from writting this : > > type 'a marshalled=string > > let make (x : 'a)=(Marshal.to_string x [] : 'a marshalled);; > > And then do all type of operations in a type safe way on strings. If I understand correctly, this is your problem: Objective Caml version 3.08.3+4 (2005-06-21) # type 'a marshalled=string;; type 'a marshalled = string # let make (x : 'a)=(Marshal.to_string x [] : 'a marshalled);; val make : 'a -> 'a marshalled = <fun> # make 1 = make "foo";; (* int marshalled is the same as string marshalled *) - : bool = false It works better you use a concrete type instead of an abbreviation: # type 'a marsh2 = Marsh of string;; type 'a marsh2 = Marsh of string # let make2 (x : 'a) = (Marsh (Marshal.to_string x []) : 'a marsh2);; val make2 : 'a -> 'a marsh2 = <fun> # make2 1 = make2 "foo";; (* int marsh2 is not the same as string marsh2 *) ^^^^^^^^^^^ This expression has type string marsh2 but is here used with type int marsh2 # -- Damien ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Caml-list] bizarre type 2005-07-03 11:42 ` Damien Doligez @ 2005-07-03 12:37 ` Jacques Garrigue 0 siblings, 0 replies; 11+ messages in thread From: Jacques Garrigue @ 2005-07-03 12:37 UTC (permalink / raw) To: caml-list From: Damien Doligez <damien.doligez@inria.fr> > If I understand correctly, this is your problem: > > Objective Caml version 3.08.3+4 (2005-06-21) > > # type 'a marshalled=string;; > type 'a marshalled = string > # let make (x : 'a)=(Marshal.to_string x [] : 'a marshalled);; > val make : 'a -> 'a marshalled = <fun> > # make 1 = make "foo";; (* int marshalled is the same as string > marshalled *) > - : bool = false > > It works better you use a concrete type instead of an abbreviation: > > # type 'a marsh2 = Marsh of string;; > type 'a marsh2 = Marsh of string > # let make2 (x : 'a) = (Marsh (Marshal.to_string x []) : 'a marsh2);; > val make2 : 'a -> 'a marsh2 = <fun> > # make2 1 = make2 "foo";; (* int marsh2 is not the same as string > marsh2 *) > ^^^^^^^^^^^ > This expression has type string marsh2 but is here used with type int > marsh2 Actually this is not a very good suggestion from the point of view of safety, as this useless parameter can still be modified by subtyping: # make2 1 = (make2 "foo" :> _ marsh2);; - : bool = false If you care about safety, you must either use an abstract type, or a private type in ocaml-3.09 (not 3.08!). On the other, if you want to keep the possibility of overriding the parameter, while detecting non-annotated cases, this may actually be a good approach. Jacques Garrigue ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2005-07-03 12:37 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-06-30 15:48 bizarre type Julien Verlaguet 2005-06-30 16:49 ` [Caml-list] " Andreas Rossberg 2005-06-30 16:58 ` Julien Verlaguet 2005-06-30 17:16 ` Stephane Glondu 2005-06-30 17:24 ` Andreas Rossberg 2005-06-30 18:30 ` Julien Verlaguet 2005-06-30 19:37 ` Andreas Rossberg 2005-06-30 21:42 ` Julien Verlaguet 2005-06-30 23:57 ` Jacques Garrigue 2005-07-03 11:42 ` Damien Doligez 2005-07-03 12:37 ` Jacques Garrigue
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox