Version française
Home     About     Download     Resources     Contact us    
Browse thread
Type constraint to explain that a polymorphic variants is included into another
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Sylvain Le Gall <sylvain@l...>
Subject: Type constraint to explain that a polymorphic variants is included into another
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