caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [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;
as well as URLs for NNTP newsgroup(s).