caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Default methods for module signatures
@ 2014-02-05 18:49 Yotam Barnoy
  2014-02-05 19:43 ` Martin Jambon
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Yotam Barnoy @ 2014-02-05 18:49 UTC (permalink / raw)
  To: Ocaml Mailing List

[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]

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

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

[-- Attachment #2: Type: text/html, Size: 1636 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Default methods for module signatures
  2014-02-05 18:49 [Caml-list] Default methods for module signatures Yotam Barnoy
@ 2014-02-05 19:43 ` Martin Jambon
  2014-02-05 20:03   ` Yotam Barnoy
  2014-02-05 20:10   ` Martin Jambon
  2014-02-05 19:53 ` Pippijn van Steenhoven
  2014-02-05 20:29 ` Alain Frisch
  2 siblings, 2 replies; 7+ messages in thread
From: Martin Jambon @ 2014-02-05 19:43 UTC (permalink / raw)
  To: Yotam Barnoy; +Cc: Ocaml Mailing List

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
>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Default methods for module signatures
  2014-02-05 18:49 [Caml-list] Default methods for module signatures Yotam Barnoy
  2014-02-05 19:43 ` Martin Jambon
@ 2014-02-05 19:53 ` Pippijn van Steenhoven
  2014-02-05 20:29 ` Alain Frisch
  2 siblings, 0 replies; 7+ messages in thread
From: Pippijn van Steenhoven @ 2014-02-05 19:53 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 689 bytes --]

Hi Yotam,

The way I usually do this is by making a minimal required subset module
type and then a default module that includes the overrides:

  module DefaultMonad(M :
    sig
      type 'a m
      val return : 'a -> 'a m
      val (>>=) : 'a m -> ('a -> 'b m) -> 'b m
    end) : Monad with type 'a m = 'a M.m =
  struct
    open M (* for >>= *)
    let (>>) m f = m >>= λ _ → f
    include M (* fill in the signature and possibly override above
                 definition *)
  end

Then you can pass your incomplete module (without >>) to DefaultMonad,
which implements a default for you, which you can still override in a
complete module.

Regards,
Pippijn

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Default methods for module signatures
  2014-02-05 19:43 ` Martin Jambon
@ 2014-02-05 20:03   ` Yotam Barnoy
  2014-02-05 20:10   ` Martin Jambon
  1 sibling, 0 replies; 7+ messages in thread
From: Yotam Barnoy @ 2014-02-05 20:03 UTC (permalink / raw)
  To: Martin Jambon; +Cc: Ocaml Mailing List

[-- Attachment #1: Type: text/plain, Size: 2809 bytes --]

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 <martin.jambon@ens-lyon.org>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
>>
>>
>>
>

[-- Attachment #2: Type: text/html, Size: 3805 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Default methods for module signatures
  2014-02-05 19:43 ` Martin Jambon
  2014-02-05 20:03   ` Yotam Barnoy
@ 2014-02-05 20:10   ` Martin Jambon
  1 sibling, 0 replies; 7+ messages in thread
From: Martin Jambon @ 2014-02-05 20:10 UTC (permalink / raw)
  To: Yotam Barnoy; +Cc: Ocaml Mailing List

On Wed 05 Feb 2014 11:43:06 AM PST, 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. :-)

The following works, but each optional field must be explicitely set to 
None:

module type Partial = sig
  val x : int option
end

module type Full = sig
  val x : int
end

module Complete (X : Partial) : Full = struct
  include X
  let x =
    match X.x with
    | None -> 0
    | Some v -> v
end

module A = Complete (struct
  let x = None
end)

module B = Complete (struct
  let x = Some 1
end)

let () =
  assert (A.x = 0);
  assert (B.x = 1)



>
>> 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
>>
>>
>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Default methods for module signatures
  2014-02-05 18:49 [Caml-list] Default methods for module signatures Yotam Barnoy
  2014-02-05 19:43 ` Martin Jambon
  2014-02-05 19:53 ` Pippijn van Steenhoven
@ 2014-02-05 20:29 ` Alain Frisch
  2014-02-05 21:17   ` Yotam Barnoy
  2 siblings, 1 reply; 7+ messages in thread
From: Alain Frisch @ 2014-02-05 20:29 UTC (permalink / raw)
  To: Yotam Barnoy, Ocaml Mailing List

I proposed (13 years ago...) a small patch to support optional fields in 
modules.  This would help achieving the desired effect. See:

http://alain.frisch.fr/info/patch-option-announce
http://alain.frisch.fr/info/patch-option

-- Alain


On 2/5/2014 7:49 PM, 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
>
> 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
>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Default methods for module signatures
  2014-02-05 20:29 ` Alain Frisch
@ 2014-02-05 21:17   ` Yotam Barnoy
  0 siblings, 0 replies; 7+ messages in thread
From: Yotam Barnoy @ 2014-02-05 21:17 UTC (permalink / raw)
  To: Alain Frisch; +Cc: Ocaml Mailing List

[-- Attachment #1: Type: text/plain, Size: 1976 bytes --]

Very nice proposal. I'm not crazy about the word 'virtual' since it doesn't
really mean anything (and has been brutally abused in C++), but that's
obviously a minor nitpick. Any reason this patch wasn't picked up?

-Yotam


On Wed, Feb 5, 2014 at 3:29 PM, Alain Frisch <alain@frisch.fr> wrote:

> I proposed (13 years ago...) a small patch to support optional fields in
> modules.  This would help achieving the desired effect. See:
>
> http://alain.frisch.fr/info/patch-option-announce
> http://alain.frisch.fr/info/patch-option
>
> -- Alain
>
>
>
> On 2/5/2014 7:49 PM, 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
>>
>> 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
>>
>>
>>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>

[-- Attachment #2: Type: text/html, Size: 3192 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-02-05 21:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-05 18:49 [Caml-list] Default methods for module signatures Yotam Barnoy
2014-02-05 19:43 ` Martin Jambon
2014-02-05 20:03   ` Yotam Barnoy
2014-02-05 20:10   ` Martin Jambon
2014-02-05 19:53 ` Pippijn van Steenhoven
2014-02-05 20:29 ` Alain Frisch
2014-02-05 21:17   ` Yotam Barnoy

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).