From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p3D5RLrE029411 for ; Wed, 13 Apr 2011 07:27:22 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aq0BABMzpU3RVdK0mGdsb2JhbAClfwgUAQEBAQEICQ0HFCWoco0LhUOJDQEBAwaFaASFXIgQhGqEXDqBIg X-IronPort-AV: E=Sophos;i="4.64,202,1301868000"; d="scan'208";a="92761903" Received: from mail-iy0-f180.google.com ([209.85.210.180]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 13 Apr 2011 07:27:16 +0200 Received: by iyf40 with SMTP id 40so366390iyf.39 for ; Tue, 12 Apr 2011 22:27:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:subject:mime-version:content-type:from :in-reply-to:date:cc:content-transfer-encoding:message-id:references :to:x-mailer; bh=fIEpb6bGnbdgqzNnOSzL6N3NP9FgRhnq+ELJ7xJYmS8=; b=hIILoMGfDVwQk63qRPvg58VhZL2pL/brSDx7R2bReUiK5VzSyLx826A30uGBV9oWLl T1d/TiVbw08Rx4fk14kI083D3rbx53RaklXNv8Q4K+iSa1DV37DShVYOK/LCoKuZuKmf /4DNplq6V0RCPC5CL219eIOmHHZmZgGPXFt9Q= 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 :content-transfer-encoding:message-id:references:to:x-mailer; b=J11VZc3Raq142tiEqpFeA+a/Rq6+Bxy2nUadkTEYUPDmfF1TfrHtdiC0w2P3TX3D7l rVEqAcak9sbAXzVhmxJQNPRBGpfvP/UpgGkY3W+XIY7L7SiYJGAtrHwZInWkVfXg8L2u 1Te+23WuUkKXsfbCYfd3QCGdRZY0cOiDUN1IQ= Received: by 10.42.147.197 with SMTP id o5mr10508453icv.475.1302672434552; Tue, 12 Apr 2011 22:27:14 -0700 (PDT) Received: from tet.garrigue.jp (58x158x128x157.ap58.ftth.ucom.ne.jp [58.158.128.157]) by mx.google.com with ESMTPS id hc41sm171993ibb.13.2011.04.12.22.27.12 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 12 Apr 2011 22:27:13 -0700 (PDT) Sender: Jacques Garrigue Mime-Version: 1.0 (Apple Message framework v1084) Content-Type: text/plain; charset=us-ascii From: Jacques Garrigue In-Reply-To: <4DA52686.40200@itpl.co.jp> Date: Wed, 13 Apr 2011 14:27:10 +0900 Cc: caml-list Message-Id: References: <4DA52686.40200@itpl.co.jp> To: Satoshi Ogasawara X-Mailer: Apple Mail (2.1084) Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p3D5RLrE029411 Subject: Re: [Caml-list] concept style using first-class module On 2011/04/13, at 13:28, Satoshi Ogasawara wrote: > Recently I learned concept style generic programming like Haskell type-class. > I'd like to emulate that style in OCaml using first-class modules. > > e.g. > > module type Monad = sig > type 'a t > val return : 'a -> 'a t > val bind : 'a t -> ('a -> 'b t) -> 'b t > end > > module type MonadPlus = sig > type 'a t > include Monad with type 'a t := 'a t > val zero : 'a t > val plus : 'a t -> 'a t -> 'a t > end > > let foo (module M:MonadPlus) m = M.bind m (fun x -> M.return x) > > But above code makes an error at the last line. > > Error: This `let module' expression has type 'a M.t -> 'a M.t > In this type, the locally bound module name M escapes its scope > > I have tried to add a (type s) parameter and specialize module > types but It's not work. > > How can I make this code typable? Is it impossible without higher > order type operator? Unfortunately, you gave yourself the answer: one would need higher kinded type variables to do that (they have them in Haskell). Namely, in order to use M.t in the result, you need to bind it somewhere, but a first-class module type cannot bind a type, and (type s) only works with parameterless types. Note that the extension allowing parameterized types in first-class module with clauses does not help either, since it doesn't bind the type constructor either, just allows to pass it around. So you have to use a real functor here: module Foo(M:MonadPlus) = struct let foo m = M.bind m (fun x -> M.return x) end You can also wrap this functor in a first-class module, but I don't see how it would help. Sorry, Jacques