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 mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id BC959BC57 for ; Tue, 27 Apr 2010 02:23:24 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuIBAInL1UuFBoIFl2dsb2JhbACcWwEBAQEBCBUHM7IEjm0BBIULgzs X-IronPort-AV: E=Sophos;i="4.52,276,1270418400"; d="scan'208";a="57861493" Received: from rabbit.math.nagoya-u.ac.jp (HELO mailhost.math.nagoya-u.ac.jp) ([133.6.130.5]) by mail1-smtp-roc.national.inria.fr with ESMTP; 27 Apr 2010 02:23:22 +0200 Received: from mailhost.math.nagoya-u.ac.jp (localhost [127.0.0.1]) by mailhost.math.nagoya-u.ac.jp (Postfix) with ESMTP id 19953B78C; Tue, 27 Apr 2010 09:23:20 +0900 (JST) Received: from mailhost.math.nagoya-u.ac.jp (camel-172 [172.16.254.4]) by mailhost.math.nagoya-u.ac.jp (Postfix) with ESMTP id C1FDD8893; Tue, 27 Apr 2010 09:23:19 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=math.nagoya-u.ac.jp; h= date:message-id:to:cc:subject:from:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=alpha; bh=KHg/Rg7UeTnVudti+ZP4Tkc72Hs=; b=fXcFZpxo7mrGXb3JIUynnfTZ3XAa Vs0gPshL3UKaibYi2XTlqVOTzq7MODdnmwyuRqm2/N9r8fv9h1czyRENwv25N2pZ Ur/PNLTq8TkHcJcnYps+/0P3ikkuksocFzrtubNMRP3q+y3hxYMTD+Gsoo/LbE3k dozAx1giE2SK0Hw= DomainKey-Signature: a=rsa-sha1; h=Received:Date:Message-Id:To:Cc:Subject:From:In-Reply-To:References:X-Mailer:Mime-Version:Content-Type:Content-Transfer-Encoding; b=Ex9n8ZOO54g5I6Q+8U0zJx40hJqbVDQGQXuM2NS0RTd6JIHI+fcPO8mXIzUIkiQmpl6MoCLA17335tHcUxQhfY3EgNYPm5ukKm7ilLPm+dG2CAKZeqYtzC2vmhtfh9/BXktrmhxEkBCD3wH3u/X6KPXqyEzKMVr5kyKxiVboEQc=; c=nofws; d=math.nagoya-u.ac.jp; q=dns; s=alpha Received: from localhost (bsdserver02 [172.16.249.2]) by mailhost.math.nagoya-u.ac.jp (Postfix) with ESMTP id 9B1EC888D; Tue, 27 Apr 2010 09:23:19 +0900 (JST) Date: Tue, 27 Apr 2010 09:23:19 +0900 (JST) Message-Id: <20100427.092319.160739744.garrigue@math.nagoya-u.ac.jp> To: d0@wp.pl Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Module type of a structure returned by functor From: Jacques Garrigue In-Reply-To: <4BD229E4.4050003@wp.pl> References: <4BD229E4.4050003@wp.pl> X-Mailer: Mew version 6.3 on Emacs 22.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; functor:01 functor:01 sig:01 sig:01 val:01 foo:01 struct:01 foo:01 struct:01 ocaml:01 val:01 ocaml:01 signatures:01 caml-list:01 int:01 From: Dawid Toton > 1. The following piece of code contains illegal constructs. These are > functor applications marked with (* ? *). > Basically, I need module type of what is produced by functor. > My first question is: what is the proper, "canonical" workaround for > unavailability of applications marked (* ? *) ? > > module type Big = sig type t type u end > module type Small = sig type t end > > module type MakeEdge = functor (Big : Big) -> sig val foo : Big.t > option end > module MakeEdge = functor (Big : Big) -> struct let foo = None end > > module type Add_boilerplate = functor (Small:Small) -> sig type t end > module Add_boilerplate = functor (Small:Small) -> struct type t = > Small.t type u = t end > > module type ConvenientEdge = functor (Small:Small) -> MakeEdge > (Add_boilerplate (Small)) (* ? *) > module ConvenientEdge = functor (Small:Small) -> MakeEdge > (Add_boilerplate (Small)) > > module SmallX = struct type t = int end > module EdgeX = ConvenientEdge (SmallX) > module type EdgeX = ConvenientEdge (SmallX) (* ? *) > > module Algorithm = functor (EdgeX : EdgeX) -> struct let doit = > EdgeX.foo end > > 2. And the related question: why one can't do functor applications in > module types as in above lines marked with (* ? *) ? Is there some > theoretical reason? You are mixing two things: the signature of a functor (which cannot be applied to anything, since it is a signature, not a functor), and a functor returning a signature. Using ocaml 3.11, you have to wrap the returned signature inside a structure: (* Signature wrapped inside a structure *) module MakeEdgeSig (Big : Big) = struct module type S = sig val foo : Big.t option end end module MakeEdge (Big : Big) = struct let foo = None end module Add_boilerplate (Small:Small) = struct type t = Small.t type u = t end module ConvenientEdgeSig (Small:Small) = MakeEdgeSig (Add_boilerplate (Small)) module ConvenientEdge (Small:Small) = MakeEdge (Add_boilerplate (Small)) module SmallX = struct type t = int end module EdgeX = ConvenientEdge (SmallX) (* Build the corresponding signature *) module type EdgeX = ConvenientEdgeSig(SmallX).S module Algorithm (EdgeX : EdgeX) = struct let doit = EdgeX.foo end > 3. Will the "module type of..." feature of 3.12 help with this? I can > imagine e.g.: > > module type EdgeX = (module type of (ConvenientEdge (SmallX))) Indeed, if your only goal is to obtain this specific signature, this does the trick. But if you want to specify signatures independently of implementations, you can also use the new destructive substitution mechanism. (* Requires ocaml 3.12 *) (* New signature Edge, parameterized with t *) module type Edge = sig type t val foo : t option end (* Edge with type t := Big.t == sig val foo : Big.t option end *) module MakeEdge (Big : Big) : Edge with type t := Big.t = struct let foo = None end module Add_boilerplate (Small:Small) = struct type t = Small.t type u = t end module ConvenientEdge (Small:Small) : Edge with type t := Small.t = MakeEdge(Add_boilerplate (Small)) module SmallX = struct type t = int end module EdgeX = ConvenientEdge (SmallX) (* Build the result signature by instantiating Edge signature *) module type EdgeX = Edge with type t := SmallX.t (* Alternative approach, obtain the same signature from EdgeX itself *) module type EdgeX' = module type of EdgeX module Algorithm(EdgeX : EdgeX) = struct let doit = EdgeX.foo end Hope this helps, Jacques Garrigue