From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id F27BA7F7C2 for ; Wed, 5 Feb 2014 21:04:03 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of yotambarnoy@gmail.com) identity=pra; client-ip=209.85.216.177; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yotambarnoy@gmail.com"; x-sender="yotambarnoy@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of yotambarnoy@gmail.com designates 209.85.216.177 as permitted sender) identity=mailfrom; client-ip=209.85.216.177; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yotambarnoy@gmail.com"; x-sender="yotambarnoy@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-qc0-f177.google.com) identity=helo; client-ip=209.85.216.177; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yotambarnoy@gmail.com"; x-sender="postmaster@mail-qc0-f177.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjwCAIeY8lLRVdixlGdsb2JhbABZhBu+ToEICBYOAQEBAQcLCwkSKoIlAQEEAScZARsPDgEDAQsGBQsNLiIBEQEFARwGEwgTh1UBAwkIoUqMXoMJk3cKGScNZIgqEQEFDI5pB4Q4BIlJjmKQNBgphHce X-IPAS-Result: AjwCAIeY8lLRVdixlGdsb2JhbABZhBu+ToEICBYOAQEBAQcLCwkSKoIlAQEEAScZARsPDgEDAQsGBQsNLiIBEQEFARwGEwgTh1UBAwkIoUqMXoMJk3cKGScNZIgqEQEFDI5pB4Q4BIlJjmKQNBgphHce X-IronPort-AV: E=Sophos;i="4.95,788,1384297200"; d="scan'208";a="57034148" Received: from mail-qc0-f177.google.com ([209.85.216.177]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 05 Feb 2014 21:04:03 +0100 Received: by mail-qc0-f177.google.com with SMTP id i8so1480807qcq.8 for ; Wed, 05 Feb 2014 12:04:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=SMjEcZIIzVA2D6x/n0M7V+WYD+P/xmjxhdTueTiNeHs=; b=wyo7rIhrTFM7MQwUaaoa8wPYBCuhetvrmRxvRFN57lMopORRSsae6nQ7x7Z/pQTScN So4/PQR2mH+L4Onp2d8JsVWh7xCJa6uAJLhmbAmt20xGEoM+HMPA9cZFZGU/xWsSg9+g eIIBbFJtkh0XXsUupJzfmzN97d9p9eQQxCE7Z+67J88gGR2OzOqhPcU/Yg14PzOsrYIY ryjYo6Qh5W8//y1dGjv4J6G2wIwoAljIzOroSD3Z3RU/WK9CDSdCh0dVPvPO4g6kSFp9 CRc9lf2u0qn9nnFFb04CzOjk/pKuN5KbA63asGM3gxWNqyNaoGVWelX85tEJqZVaVfcG eaIQ== X-Received: by 10.140.20.17 with SMTP id 17mr5770136qgi.28.1391630642267; Wed, 05 Feb 2014 12:04:02 -0800 (PST) MIME-Version: 1.0 Received: by 10.224.106.137 with HTTP; Wed, 5 Feb 2014 12:03:42 -0800 (PST) In-Reply-To: <52F2944A.3000908@ens-lyon.org> References: <52F2944A.3000908@ens-lyon.org> From: Yotam Barnoy Date: Wed, 5 Feb 2014 15:03:42 -0500 Message-ID: To: Martin Jambon Cc: Ocaml Mailing List Content-Type: multipart/alternative; boundary=001a11c124f61751bb04f1ae4218 Subject: Re: [Caml-list] Default methods for module signatures --001a11c124f61751bb04f1ae4218 Content-Type: text/plain; charset=ISO-8859-1 OK so just to clarify, the functor method you suggested does the opposite of what I was looking for: if my original module (which I wrote to match an interface) has no 'default function', it adds it, but if my original module provided that function, it's overridden. What I'm looking for is a solution whereby if my original module is missing an interface function, that function is added, but if it already contains a function, the original function takes precedence. More specifically regarding my example (just to illustrate the idea): the Monad module will be used by other functors to do things, so the Monad interface must define the full interface, including >>. On Wed, Feb 5, 2014 at 2:43 PM, Martin Jambon wrote: > On Wed 05 Feb 2014 10:49:29 AM PST, Yotam Barnoy wrote: > >> Hello List >> >> I would like the following feature, and I'm not enough of an expert in >> module-fu to know if something like this is doable. >> >> Suppose I have a module signature of >> >> module type Monad = sig >> type 'a m >> val return : 'a -> 'a m >> val (>>=) : 'a m -> ('a -> 'b m) -> 'b m >> val (>>) : 'a m -> 'b m -> 'b m >> end >> >> I would like to have a default implementation for (>>), since a simple >> default implementation is >> >> let (>>) m f = m >>= fun _ -> f >> >> Alternatively, I would like to include this from some DefaultMonad >> module, but have the (>>=) referred to in the function be my newly >> defined (>>=) implementation (ie. late binding). Is there currently >> any way to do this? If not, would there be a way to implement a >> partial default implementation built into or associated with a module >> signature? Something like >> > > OCaml has functors but they don't support optional fields in their > arguments. > > You can create a functor Monad.Make that takes a module without (>>) and > creates a module with an extra (>>) field. However, if the input module > contains (>>) already, the new implementation will override it as in this > minimal example: > > # module A = struct end;; > module A : sig end > > # module M(A: module type of A) = struct include A let x = 0 end;; > module M : functor (A : sig end) -> sig val x : int end > > # module B = M(struct end);; > module B : sig val x : int end > > # module C = M(struct let x = 1 end);; > module C : sig val x : int end > > # C.x;; > - : int = 0 > > C.x is 0, not 1. > > > There may be clever tricks to support some kind of optional module field > pattern, though. I'll let others scratch their heads. :-) > > > > module type Monad = sig... default struct... end >> >> Haskell has this available as part of the semantics of their typeclass >> system, and I think it would be really handy to have (if there isn't >> already a way to do it currently). >> >> -Yotam >> >> >> > --001a11c124f61751bb04f1ae4218 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
OK so just to clarify, the functor method you suggest= ed does the opposite of what I was looking for: if my original module (whic= h I wrote to match an interface) has no 'default function', it adds= it, but if my original module provided that function, it's overridden.= What I'm looking for is a solution whereby if my original module is mi= ssing an interface function, that function is added, but if it already cont= ains a function, the original function takes precedence.

More specifically regarding my example (just to illustrate the id= ea): the Monad module will be used by other functors to do things, so the M= onad interface must define the full interface, including >>.




On Wed, Feb 5, 2014 at 2:43 PM, Martin Jambon <martin.jambon@ens-lyon.org> wrote:
On Wed 05 Feb 2014 10:49:2= 9 AM PST, Yotam Barnoy wrote:
Hello List

I would like the following feature, and I'm not enough of an expert in<= br> module-fu to know if something like this is doable.

Suppose I have a module signature of

module type Monad =3D sig
=A0 type 'a m
=A0 val return : 'a -> 'a m
=A0 val (>>=3D) : 'a m -> ('a -> 'b m) -> 'b= m
=A0 val (>>) : 'a m -> 'b m -> 'b m
end

I would like to have a default implementation for (>>), since a simpl= e
default implementation is

let (>>) m f =3D m >>=3D fun _ -> f

Alternatively, I would like to include this from some DefaultMonad
module, but have the (>>=3D) referred to in the function be my newly<= br> defined (>>=3D) implementation (ie. late binding). Is there currently=
any way to do this? If not, would there be a way to implement a
partial default implementation built into or associated with a module
signature? Something like

OCaml has functors but they don't support optional fields in their argu= ments.

You can create a functor Monad.Make that takes a module without (>>) = and creates a module with an extra (>>) field. However, if the input = module contains (>>) already, the new implementation will override it= as in this minimal example:

# module A =3D struct end;;
module A : sig =A0end

# module M(A: module type of A) =3D struct include A let x =3D 0 end;;
module M : functor (A : sig =A0end) -> sig val x : int end

# module B =3D M(struct end);;
module B : sig val x : int end

# module C =3D M(struct let x =3D 1 end);;
module C : sig val x : int end

# C.x;;
- : int =3D 0

C.x is 0, not 1.


There may be clever tricks to support some kind of optional module field pa= ttern, though. I'll let others scratch their heads. :-)



module type Monad =3D sig... default struct... end

Haskell has this available as part of the semantics of their typeclass
system, and I think it would be really handy to have (if there isn't
already a way to do it currently).

-Yotam




--001a11c124f61751bb04f1ae4218--