From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id C3A4CBC57 for ; Fri, 8 Oct 2010 22:09:28 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsYBAP8Wr0zRVdI2kWdsb2JhbACiOQgVAQEBAQkLCgcRAx+jNotghnqJBAEBAwWFQgSET4Vxg2OFLA X-IronPort-AV: E=Sophos;i="4.57,305,1283724000"; d="scan'208";a="72118065" Received: from mail-pz0-f54.google.com ([209.85.210.54]) by mail2-smtp-roc.national.inria.fr with ESMTP; 08 Oct 2010 22:09:28 +0200 Received: by pzk33 with SMTP id 33so105735pzk.27 for ; Fri, 08 Oct 2010 13:09:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:subject:mime-version :content-type:from:in-reply-to:date:cc:reply-to :content-transfer-encoding:message-id:references:to:x-mailer; bh=a0gdMgZ+xV4xrkw01fvjPzqzQcNdAclmtwY/h6gyoaQ=; b=nrkOfQ3Y721DIQO4AhQUrqsPlxmukkGCKMFPFvsJwyoHi1+sTCEAaHxx3OmHEnKdNR Vj+uZUmorAqK5L6U7jPetPO02M7AzcCzU+FaqV8yJd2LoY/dB7EfV1zd4CmTQ1/7O5FD tkkEjOk+57pjEMOkzXKij84hcaeycIO8KEJ5s= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:subject:mime-version:content-type:from:in-reply-to:date:cc :reply-to:content-transfer-encoding:message-id:references:to :x-mailer; b=o0gh6BkPoye5igrdiYm8unAHtvEBPVKzr/WAxH2WNi5ThuRRS3eQrSa8gJDQCl26Pf QRWeAFKXNPqmEtxMwssH0/p9eWWZKJ5qDmKKNILHt8sa6QuLgfHzSoTA9pePTsahp0qw AGbMS+o+Gj1mp4zaXz83BOg+AC+9mdYwbRiUM= Received: by 10.142.140.2 with SMTP id n2mr1318067wfd.323.1286568567152; Fri, 08 Oct 2010 13:09:27 -0700 (PDT) Received: from tet.garrigue.jp (58x158x128x157.ap58.ftth.ucom.ne.jp [58.158.128.157]) by mx.google.com with ESMTPS id w14sm4092529wfd.6.2010.10.08.13.09.25 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 08 Oct 2010 13:09:26 -0700 (PDT) Sender: Jacques Garrigue Subject: Re: [Caml-list] Type constraint to explain that a polymorphic variants is included into another Mime-Version: 1.0 (Apple Message framework v1081) Content-Type: text/plain; charset=us-ascii From: Jacques Garrigue In-Reply-To: Date: Sat, 9 Oct 2010 05:09:23 +0900 Cc: caml-list@inria.fr Reply-To: garrigue@math.nagoya-u.ac.jp Content-Transfer-Encoding: 7bit Message-Id: References: To: Sylvain Le Gall X-Mailer: Apple Mail (2.1081) X-Spam: no; 0.00; variants:01 subset:01 subtyping:01 typable:01 struct:01 functor:01 sig:01 val:01 struct:01 prerr:01 endline:01 prerr:01 endline:01 polymorphic:01 wrote:01 On 2010/10/09, at 2:13, Sylvain Le Gall wrote: > Hello all, > > I would like to build an interface for plugins that allow to extract at the > same time a very specific data for a plugin family and to extract > general help for plugins. > > Here is an example: [...] > This code doesn't compile because I see no way to explain that F.kind is > included into plugin_kind. I'm not sure of what you are trying to do, but private rows where introduced with this goal in mind. The idea is to change the abstract definition of kind in PLUGIN_FAMILY to type kind = private [< plugin_kind] meaning that kind can be instantiated to any subset of plugin_kind. You can then use subtyping to convert from kind to plugin_kind. Here is a typable version of your code. Note that I had to do a few other changes to make the types match. Jacques (** All the plugins I want to manage *) type plugin_kind = [`Build | `Install] (** Generic plugin *) type 'a plugin = 'a * string (** Help data for all plugin *) module MapPlugin = Map.Make (struct type t = plugin_kind plugin let compare = compare end) let all_help: string MapPlugin.t ref = ref MapPlugin.empty let help plg = MapPlugin.find plg !all_help (** Functor to build function related to one type of plugin *) module type PLUGIN_FAMILY = sig type act type kind = private [< plugin_kind] val kind_default: kind end module Make (F: PLUGIN_FAMILY) = struct module MapPluginSelf = Map.Make (struct type t = F.kind plugin let compare = compare end) let all_act: F.act MapPluginSelf.t ref = ref MapPluginSelf.empty let act (plg : F.kind plugin) = MapPluginSelf.find plg !all_act let create name help act = let id = F.kind_default, name in all_help := MapPlugin.add (id :> plugin_kind * _) help !all_help; all_act := MapPluginSelf.add id act !all_act; id end (** Functions for build plugins *) module Build = Make (struct type act = unit -> unit type kind = [`Build] let kind_default = `Build end) (** Functions for install plugins *) module Install = Make (struct type act = string list -> unit type kind = [`Install] let kind_default = `Install end) type package = { name: string; plugin_build: [`Build] plugin; plugin_install: [`Install] plugin; } let run pkg = prerr_endline (help (pkg.plugin_build :> MapPlugin.key)); prerr_endline (help (pkg.plugin_install :> MapPlugin.key)); (Build.act pkg.plugin_build) (); Install.act pkg.plugin_install []