Version française
Home     About     Download     Resources     Contact us    
Browse thread
RE: [Caml-list] Width subtyping
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Yaron Minsky <yminsky@g...>
Subject: Re: [Caml-list] Width subtyping
On Sun, May 31, 2009 at 7:08 PM, Dario Teixeira <darioteixeira@yahoo.com>wrote:

>
> I also meant "heavier" in terms of efficiency.  And like David said, it
> does
> feel wrong to carry the performance penalty of the object system solely
> because
> I need the structural subtyping features.


If you're willing to give up some of the syntactic niceties of records (and
the ability to pattern-match) you can get what you want using an abstract
type.

module type S =
sig
   type 'a
t
   val create_t1 : a : int -> b : int -> c : int -> [ `a | `b | `c ]
t
   val create_t2 : a : int -> b : int -> c : int -> d :
int
     -> [ `a | `b | `c | `d ]
t
   val create_t3 : b : int -> c : int -> d : int -> [ `b | `c | `d ]
t


   val a : [> `a ] t ->
int
   val b : [> `b ] t ->
int
   val c : [> `c ] t ->
int
   val d : [> `d ] t ->
int
end



module M : S =
struct
  type u = { a: int; b: int; c :int; d: int
}
  type 'a t =
u
  let default = { a = 0; b = 0; c = 0; d = 0
}
  let create_t1 ~a ~b ~c = { default with a = a; b = b; c = c
}
  let create_t2 ~a ~b ~c ~d = { a = a; b=b; c=c; d=d;
}
  let create_t3 ~b ~c ~d =  { default with b=b; c=c; d=d
}


  let a t =
t.a
  let b t =
t.b
  let c t =
t.c
  let d t =
t.d
end



let f x = M.a x + M.b
x
let g () = f (M.create_t1 ~a:0 ~b:0 ~c:0) (* accepted by compiler
*)
let g () = f (M.create_t2 ~a:0 ~b:0 ~c:0 ~d:0) (* accepted by compiler
*)
let g () = f (M.create_t3 ~b:0 ~c:0 ~d:0) (* rejected by compiler *)

The compiler error you get on that last line is this:

Error: This expression has type [ `b | `c | `d ]
M.t
       but is here used with type [> `a | `b ]
M.t
       The first variant type does not allow tag(s) `a


Here, we've chosen to use a default value for fields that we don't fill in.
We could just as well have used options here.  The performance of the above
will be roughly the same as the performance of a simple record.  Obviously,
all of the different "subtypes" have the full record stored at a physical
level.

y