caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Sylvain Le Gall <sylvain@le-gall.net>
To: caml-list@inria.fr
Subject: Type constraint to explain that a polymorphic variants is included into another
Date: Fri, 8 Oct 2010 17:13:27 +0000 (UTC)	[thread overview]
Message-ID: <slrniauk9n.fmh.sylvain@gallu.homelinux.org> (raw)

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:

(** 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
  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 help !all_help;
      all_act  := MapPlugin.add id act !all_act;
      id
end

(** Functions for build plugins *)
module Build =
  Make
    (struct 
       type act = unit -> unit 
       type kind = [`Build]
       let default = `Build
     end)

(** Functions for install plugins *)
module Install = 
  Make
    (struct 
       type act = string list -> unit
       type kind = [`Install]
       let default = `Install
     end)

type package = 
    {
      name: string;
      plugin_build: [`Build] plugin;
      plugin_install: [`Install] plugin;
    }

let run pkg = 
  prerr_endline (help pkg.plugin_build);
  prerr_endline (help pkg.plugin_install);
  (Build.act pkg.plugin_build) ();
  (Install.act pkg.plugin_install) ()


This code doesn't compile because I see no way to explain that F.kind is
included into plugin_kind. 

Here is the precise error:
camlc -o test test.ml
File "test.ml", line 51, characters 32-34:
Error: This expression has type F.kind * 'a
       but an expression was expected of type
         MapPlugin.key = plugin_kind * string
       Type F.kind is not compatible with type
         plugin_kind = [ `Build | `Install ] 
make: *** [all] Erreur 2

Does anyone know a good solution to this problem? Does anyone have a
better solution to this problem? (different design?)

Thank you for your answers,
Sylvain Le Gall


             reply	other threads:[~2010-10-08 17:13 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-08 17:13 Sylvain Le Gall [this message]
2010-10-08 18:13 ` [Caml-list] " Jake Donham
2010-10-08 22:10   ` Sylvain Le Gall
2010-10-08 20:09 ` [Caml-list] " Jacques Garrigue
2010-10-11  8:49   ` Sylvain Le Gall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=slrniauk9n.fmh.sylvain@gallu.homelinux.org \
    --to=sylvain@le-gall.net \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).