This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

[Caml-list] const equivalent for mutable types?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
 Date: 2004-08-27 (09:03) From: Jacques GARRIGUE Subject: Re: [Caml-list] Phantom types
```From: Jon Harrop <jon@jdh30.plus.com>

>
>   val add_even_even : [> `Even ] t -> [> `Even ] t -> [> `Even ] t
>   val add_even_odd : [> `Even ] t -> [> `Odd ] t -> [> `Odd ] t
>
> allows:
>
> val k : _[> `Odd ] PhantomInt.t = <abstr>

This part is OK.

> which can then be misused:
>
> - : [ `Even ] PhantomInt.t = <abstr>

But this one is wrong.

> I think this is because [> `Even] means any superset of [ `Even ] whereas [<
> `Even], which was probably intended, means any subset of [ `Even ]. Indeed,
> the latter appears to work.

Indeed, one must be careful about variance.
So the right signature would be:
type +'a t
type any = [`Even|`Odd]
val add_even_even : [ `Even ] t -> [ `Even ] t -> [> `Even ] t
val add_even_odd : [ `Even ] t -> [ `Odd ] t -> [> `Odd ] t
val add_unknown_unknown : any t -> any t -> any t
(Note the + indicating covariance)

Then you have
# let k = PhantomInt.add_even_odd i j;;
val k : [> `Odd ] PhantomInt.t = <abstr>
(polymorphic result!)