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 1A5AB7F89E for ; Fri, 21 Mar 2014 08:31:44 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of r.poss@uva.nl) identity=pra; client-ip=146.50.108.158; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="r.poss@uva.nl"; x-sender="r.poss@uva.nl"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of r.poss@uva.nl) identity=mailfrom; client-ip=146.50.108.158; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="r.poss@uva.nl"; x-sender="r.poss@uva.nl"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@ezel.ic.uva.nl) identity=helo; client-ip=146.50.108.158; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="r.poss@uva.nl"; x-sender="postmaster@ezel.ic.uva.nl"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArMBAIHqK1OSMmyenGdsb2JhbABZFoMru3OIRhYOAQEBAQEICwkJFCiCU4EhTzOHeQQJnVqyD48CghgPZ4EUBJl7lC0 X-IPAS-Result: ArMBAIHqK1OSMmyenGdsb2JhbABZFoMru3OIRhYOAQEBAQEICwkJFCiCU4EhTzOHeQQJnVqyD48CghgPZ4EUBJl7lC0 X-IronPort-AV: E=Sophos;i="4.97,702,1389740400"; d="scan'208";a="63924550" Received: from ezel.ic.uva.nl ([146.50.108.158]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 21 Mar 2014 08:31:26 +0100 Received: from vo.home (77-172-129-60.ip.telfort.nl [77.172.129.60]) (authenticated bits=0) by ezel.ic.uva.nl (8.13.8/8.13.8) with ESMTP id s2L7VMV9015621 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Fri, 21 Mar 2014 08:31:22 +0100 From: "Raphael 'kena' Poss" Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Date: Fri, 21 Mar 2014 08:31:22 +0100 To: caml-list@inria.fr Message-Id: Mime-Version: 1.0 (Apple Message framework v1085) X-Mailer: Apple Mail (2.1085) Subject: [Caml-list] Polymorphic module type constraints Hi all, I am trying to take advantage of OCaml locally abstract types to constrain = a functor. I want to use this to support the creation of modules from user-= provided functions and some defaults. I encounter two issues with polymorph= ic types, which I am unable to solve. Maybe you will have some suggestions? To show what I want, here is an example that "works fine" but uses regular = types: module type Eq =3D sig type t val (=3D) : t -> t -> bool val (<>) : t -> t -> bool end let makeEq (type a) eq =3D let module S =3D struct type t =3D a=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=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=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=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=20=20 let (=3D) =3D eq let (<>) x y =3D not (x =3D y) end in (module S : Eq with type t =3D a) (* val eq1: int -> int -> bool *) let eq1 a b =3D (a mod 3) =3D (b mod 3) module Eq1 =3D (val makeEq eq1) Here, I encounter the first issue: (* val eq2: 'a option -> 'a option -> bool *) let eq2 a b =3D match (a, b) with | (None, None) -> true | (Some x, Some y) -> x =3D y | _ -> false module Eq2 =3D (val makeEq ~eq2)=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=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=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=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20 =3D>=20 Error: The type of this packed module contains variables: (module Eq with type t =3D 'a option) Is there any way to generalize? Now, the other issue is when the signature explicitly declares a polymorphi= c type: module type Poly =3D sig type 'a t end module type Mappable =3D sig type 'a t=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=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= =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=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=20=20 val map : ('a -> 'b) -> 'a t -> 'b t end So far so good; but how to define makeMappable function, that takes a map f= unction and Poly module and defines a Mappable instance from them? My first try: let makeMappable1 (type s) (module O : Poly with type t =3D s) map =3D let module S : Mappable with type 'a t =3D 'a O.t =3D struct include O let map : ('a -> 'b) -> 'a t -> 'b t =3D map end in (module S) =3D>=20 Error: In this `with' constraint, the new definition of t does not match its original definition in the constrained signature: Type declarations do not match: type t is not included in type 'a t Ok, fair enough: let makeMappable2 (type s) (module O : Poly with type 'a t =3D s) map =3D let module S : Mappable with type 'a t =3D 'a O.t =3D ... =3D> Error: Syntax error: module-expr expected. (location: with type ... on fi= rst line) So, I try to fix this with: let makeMappable3 (module O : Poly) map =3D let module S : Mappable with type 'a t =3D 'a O.t =3D struct include O let map : ('a -> 'b) -> 'a t -> 'b t =3D map end in (module S)=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=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=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=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 =3D> Error: This expression has type ('a -> 'b) -> 'a O.t -> 'b t but an expression was expected of type ('a -> 'b) -> 'a O.t -> 'b t The type constructor O.t would escape its scope Any suggestion as to how to define makeMappable? Thanks in advance, --=20 Raphael 'kena' Poss =B7 r.poss@uva.nl http://staff.science.uva.nl/~poss/