* [Caml-list] deep coercion does not work for some stdlib types @ 2013-02-01 20:27 Ashish Agarwal 2013-02-01 20:39 ` Lukasz Stafiniak 0 siblings, 1 reply; 5+ messages in thread From: Ashish Agarwal @ 2013-02-01 20:27 UTC (permalink / raw) To: Caml List [-- Attachment #1: Type: text/plain, Size: 1022 bytes --] Section 7.9.2 of the manual gives this example: http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc76 # module N : sig type t = private int val of_int: int -> t val to_int: t -> int end = struct type t = int let of_int n = assert (n >= 0); n let to_int n = n end;; module N : sig type t = private int val of_int : int -> t val to_int : t -> int end Deep coercion to a list of integers works as expected: # let l = List.map N.of_int [1;2;3];; val l : N.t list = [1; 2; 3] # (l :> int list);; - : int list = [1; 2; 3] But for arrays it doesn't work: # let a = Array.of_list l;; val a : N.t array = [|1; 2; 3|] # (a :> int array);; Error: Type N.t array is not a subtype of int array Is this because the array type does not have a variance annotation? If so, why doesn't it? I can get around this by mapping over the elements: # Array.map (fun (x : N.t) -> (x :> int)) a;; But am I right that coercions have no run-time cost, as where the mapping will? [-- Attachment #2: Type: text/html, Size: 1666 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] deep coercion does not work for some stdlib types 2013-02-01 20:27 [Caml-list] deep coercion does not work for some stdlib types Ashish Agarwal @ 2013-02-01 20:39 ` Lukasz Stafiniak 2013-02-01 20:44 ` Lukasz Stafiniak ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Lukasz Stafiniak @ 2013-02-01 20:39 UTC (permalink / raw) To: Ashish Agarwal; +Cc: Caml List On Fri, Feb 1, 2013 at 9:27 PM, Ashish Agarwal <agarwal1975@gmail.com> wrote: > > But for arrays it doesn't work: > > # let a = Array.of_list l;; > val a : N.t array = [|1; 2; 3|] > > # (a :> int array);; > Error: Type N.t array is not a subtype of int array > > Is this because the array type does not have a variance annotation? If so, > why doesn't it? You must have heard about the "mistake" of Go having covariant arrays. In OCaml, arrays are invariant because they are mutable. After you have coerced "let b = (a :> X.t array)", you can modify "a.(0) <- y" with a value "y" that is not "X.t". It would be great to have a separate type "tuple", supported by Pervasives, that differs from "array" only in that it is immutable and covariant. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] deep coercion does not work for some stdlib types 2013-02-01 20:39 ` Lukasz Stafiniak @ 2013-02-01 20:44 ` Lukasz Stafiniak 2013-02-01 23:37 ` Ashish Agarwal 2013-02-02 1:33 ` Jacques Garrigue 2 siblings, 0 replies; 5+ messages in thread From: Lukasz Stafiniak @ 2013-02-01 20:44 UTC (permalink / raw) To: Ashish Agarwal; +Cc: Caml List On Fri, Feb 1, 2013 at 9:39 PM, Lukasz Stafiniak <lukstafi@gmail.com> wrote: > > You must have heard about the "mistake" of Go having covariant arrays. Obviously I've got my facts wrong... sorry. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] deep coercion does not work for some stdlib types 2013-02-01 20:39 ` Lukasz Stafiniak 2013-02-01 20:44 ` Lukasz Stafiniak @ 2013-02-01 23:37 ` Ashish Agarwal 2013-02-02 1:33 ` Jacques Garrigue 2 siblings, 0 replies; 5+ messages in thread From: Ashish Agarwal @ 2013-02-01 23:37 UTC (permalink / raw) To: Lukasz Stafiniak; +Cc: Caml List [-- Attachment #1: Type: text/plain, Size: 152 bytes --] On Fri, Feb 1, 2013 at 3:39 PM, Lukasz Stafiniak <lukstafi@gmail.com> wrote: arrays are invariant because they are mutable Thanks. That explains it. [-- Attachment #2: Type: text/html, Size: 443 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] deep coercion does not work for some stdlib types 2013-02-01 20:39 ` Lukasz Stafiniak 2013-02-01 20:44 ` Lukasz Stafiniak 2013-02-01 23:37 ` Ashish Agarwal @ 2013-02-02 1:33 ` Jacques Garrigue 2 siblings, 0 replies; 5+ messages in thread From: Jacques Garrigue @ 2013-02-02 1:33 UTC (permalink / raw) To: Lukasz Stafiniak; +Cc: Ashish Agarwal, Caml List On 2013/02/02, at 5:39, Lukasz Stafiniak <lukstafi@gmail.com> wrote: > On Fri, Feb 1, 2013 at 9:27 PM, Ashish Agarwal <agarwal1975@gmail.com> wrote: >> >> But for arrays it doesn't work: >> >> # let a = Array.of_list l;; >> val a : N.t array = [|1; 2; 3|] >> >> # (a :> int array);; >> Error: Type N.t array is not a subtype of int array >> >> Is this because the array type does not have a variance annotation? If so, >> why doesn't it? > > You must have heard about the "mistake" of Go having covariant arrays. > In OCaml, arrays are invariant because they are mutable. After you > have coerced "let b = (a :> X.t array)", you can modify "a.(0) <- y" > with a value "y" that is not "X.t". > > It would be great to have a separate type "tuple", supported by > Pervasives, that differs from "array" only in that it is immutable and > covariant. Well, if you do not care too much about performance, you can do it by wrapping your array in an object or record: class [+'a] vector (arr : 'a array) = object val arr = arr method length = Array.length arr method get = Array.get arr method iter f = Array.iter f arr end type p = private int let coerce x = (x : p vector :> int vector) or type +'a vector = {length: int; get: int -> 'a; iter: ('a -> unit) -> unit} let vector arr = Array.({length=length arr; get=get arr; iter = fun f -> iter f arr}) let coerce x = (x : p vector :> int vector) Note that the object based approach is slightly weaker because, while vector is covariant, it is not strongly covariant, as needed for the relaxed value restriction. This can be fixed by making it abstract. Jacques Garrigue ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-02-02 1:33 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-02-01 20:27 [Caml-list] deep coercion does not work for some stdlib types Ashish Agarwal 2013-02-01 20:39 ` Lukasz Stafiniak 2013-02-01 20:44 ` Lukasz Stafiniak 2013-02-01 23:37 ` Ashish Agarwal 2013-02-02 1:33 ` Jacques Garrigue
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox