Version française
Home     About     Download     Resources     Contact us    
Browse thread
[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: -- (:)
From: Jacques GARRIGUE <garrigue@k...>
Subject: Re: [Caml-list] Phantom types
From: Jon Harrop <jon@jdh30.plus.com>

> I should add, using:
> 
>   val add_even_even : [> `Even ] t -> [> `Even ] t -> [> `Even ] t
>   val add_even_odd : [> `Even ] t -> [> `Odd ] t -> [> `Odd ] t
> 
> allows:
> 
> # PhantomInt.add_even_odd i j;;
> val k : _[> `Odd ] PhantomInt.t = <abstr>

This part is OK.

> which can then be misused:
> 
> # PhantomInt.add_even_even i k;;
> - : [ `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!)
# PhantomInt.add_even_even i k;;
** type error
# PhantomInt.add_unknown_unknown i k;;
- : any t = <abstr>

Jacques Garrigue

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