From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id A89F77FACB for ; Sat, 23 Aug 2014 17:07:01 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of daniel.buenzli@erratique.ch) identity=pra; client-ip=74.55.86.74; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="daniel.buenzli@erratique.ch"; x-sender="daniel.buenzli@erratique.ch"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of daniel.buenzli@erratique.ch) identity=mailfrom; client-ip=74.55.86.74; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="daniel.buenzli@erratique.ch"; x-sender="daniel.buenzli@erratique.ch"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@smtp.webfaction.com) identity=helo; client-ip=74.55.86.74; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="daniel.buenzli@erratique.ch"; x-sender="postmaster@smtp.webfaction.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtABAKet+FNKN1ZKnGdsb2JhbABZhhGBIrNinVABgR0QAQEBAQEGDQkJFCmEBAEFIwRSEAsaAiYCAkcQBhsTiCcEr3CURxeBLI0+EQEdMweCeTaBHQWGEYwTkTwYkTyBeoFAAQEB X-IPAS-Result: AtABAKet+FNKN1ZKnGdsb2JhbABZhhGBIrNinVABgR0QAQEBAQEGDQkJFCmEBAEFIwRSEAsaAiYCAkcQBhsTiCcEr3CURxeBLI0+EQEdMweCeTaBHQWGEYwTkTwYkTyBeoFAAQEB X-IronPort-AV: E=Sophos;i="5.04,386,1406584800"; d="scan'208";a="90870231" Received: from mail6.webfaction.com (HELO smtp.webfaction.com) ([74.55.86.74]) by mail2-smtp-roc.national.inria.fr with ESMTP; 23 Aug 2014 17:07:00 +0200 Received: from [172.20.10.2] (188.29.164.28.threembb.co.uk [188.29.164.28]) by smtp.webfaction.com (Postfix) with ESMTP id 096CA20F13E2; Sat, 23 Aug 2014 15:06:56 +0000 (UTC) Date: Sat, 23 Aug 2014 16:06:50 +0100 From: =?utf-8?Q?Daniel_B=C3=BCnzli?= To: Philippe Veber Cc: Caml-list , Pierre Chambart Message-ID: In-Reply-To: References: <4060AF3441F149839C46804E64E2B9CE@erratique.ch> <83ADBE14262643EA9519BBE719987901@erratique.ch> X-Mailer: sparrow 1.6.4 (build 1178) MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Subject: Re: [Caml-list] Phantom types and variants Le vendredi, 22 ao=C3=BBt 2014 =C3=A0 20:49, Philippe Veber a =C3=A9crit : > Here is another proposal: Thanks Philippe. I also thought about this solution but I wanted to avoid t= he new allocation. Note that you can actually write that solution without h= aving to write that eq function. This makes the trick: let coerce kind v =3D match kind with | kind when (kind :> kind) =3D (v.kind :> kind) -> { v with kind =3D kind } | _ -> invalid_arg "" Pierre Chambart also responded to me privately (thanks), suggesting that I = do not try to use variants themselves as the coercion specification but ano= ther more structured value. His solution (at the end of this email) works. = But since I'm a little bit stubborn and that I would really like to use the= variant for the coercion specification I tried to adapt its solution as fo= llows. But it fails with a type error that I fail to understand: Error: This definition has type ([< kind ] as 'a) -> 'a t which is less general than 'b. ([< kind ] as 'b) -> 'b t ------------- module M : sig type kind =3D [ `A | `B ] type +'a t constraint 'a =3D [< kind ] val a : unit -> [> `A] t val b : unit -> [> `B] t val coerce : ([< kind] as 'a) -> 'b t -> 'a t end =3D struct type kind =3D [ `A | `B ] type +'a t =3D { kind : kind; coerce : 'b. ([< kind] as 'b) -> 'b t } constraint 'a =3D [< kind ] let a () =3D let rec v =3D { kind =3D `A; coerce } and coerce : 'b. ([< kind] as 'b) -> 'b t =3D function | `A -> v | `B -> invalid_arg "" in v let b () =3D let rec v =3D { kind =3D `B; coerce } and coerce : 'b. ([< kind] as 'b) ->'b t =3D function | `A -> v | `B -> invalid_arg "" in v let coerce kind v =3D v.coerce kind end ----------- Any hints ?=20=20 Best, Daniel Pierre Chambart's solution: module M : sig type kind =3D [ `A | `B ] type +'a t constraint 'a =3D [< kind ] type 'a coercer constraint 'a =3D [< kind] =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20 val a : unit -> [> `A] t val b : unit -> [> `B] t=20=20=20=20=20=20=20 val ac : [`A] coercer val coerce : 'a coercer -> 'b t -> 'a t=20=20=20=20=20=20=20 end =3D struct type kind =3D [ `A | `B ] type +'a t =3D { kind : kind } constraint 'a =3D [< kind] =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 type 'a coercer =3D { f : 'b. 'b t -> 'a t option } constraint 'a =3D [< kind] =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 let a () =3D { kind =3D `A } let b () =3D { kind =3D `B } =20=20=20=20=20=20=20=20=20=20=20=20=20=20 let ac =3D { f =3D (function ({ kind =3D `A } as v) -> Some v | _ -> None) } =20=20=20=20=20 let coerce k v =3D match k.f v with | None -> invalid_arg "" | Some v -> v end