English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

Browse thread
Width subtyping
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2009-05-29 (14:43)
From: David Allsopp <dra-news@m...>
Subject: RE: [Caml-list] Width subtyping
> Though it is probably been-there-done-that material for the veterans in
> this list, for the sake of the not-so-veterans I have to ask: how do you guys
> typically model width subtyping in Ocaml?

Definitely not a veteran, but might private types help a little?

> Consider for example three record types that share some of their fields:
> type t1 = {a: int; b: int; c: int;        }
> type t2 = {a: int; b: int; c: int; d: int;}
> type t3 = {        b: int; c: int; d: int;}

Modelled as...

module M : sig
  type t' = {a: int; b: int; c: int; d: int}
  type t = private T1 of t' | T2 of t' | T3 of t'
  val makeT1 : int -> int -> int -> t
  val makeT2 : int -> int -> int -> int -> t
  val makeT3 : int -> int -> int -> t
end = struct
  type t' = {a: int; b: int; c: int; d: int}

  type t = T1 of t' | T2 of t' | T3 of t'

  let makeT1 a b c = T1 {a = a; b = b; c = c; d = 0}
  let makeT2 a b c d = T2 {a = a; b = b; c = c; d = d}
  let makeT3 b c d = T3 {a = 0; b = b; c = c; d = d}

This way you're always dealing with the same product type, but the sum type tells you which fields are actually valid. Of course, it relies on there being an obvious sentinel value for unused fields (otherwise you just end up with 'a option everywhere) and I still don't think it's that neat as you can still match against fields which aren't valid but at least the type system prevents you from being handed an illegal value. The benefit is that you don't need special "get" functions (just a match on type t to extract the t' value from each constructor). I can't get my head around how private polymorphic variants work to see if they can refine this further...