caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] with clause
@ 2011-10-07 16:37 Walter Cazzola
  2011-10-09 15:42 ` Gabriel Scherer
  0 siblings, 1 reply; 2+ messages in thread
From: Walter Cazzola @ 2011-10-07 16:37 UTC (permalink / raw)
  To: OCaML Mailing List

[-- Attachment #1: Type: TEXT/PLAIN, Size: 651 bytes --]

Dear all,
I'm still stucked on my example to write a functor for functions with a
variable number of arguments. In particular I can't instantiate it with
a generic list ('a list).

Attached you find my code. Sometimes ago some on the list suggested me
to  use with to specify the value of the generic type (a in my case but
I can't get rid of its syntax, what I think correct is:

   module M1 = VarArgs(ListConcat with type ListConcat.a = int) ;;

but I get a syntax error on the with.

Please note that I'd like to keep OpVarADT and varargs independent of
the concrete type of a.

Any help to solve this riddle would be appreciated.

TIA
Walter

-- 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 101 bytes --]

module type OpVarADT = 
 sig
   type a and b and c
   val op: a -> b -> c
   val init : c
 end

[-- Attachment #3: Type: TEXT/PLAIN, Size: 161 bytes --]

module VarArgs (OP : OpVarADT.OpVarADT) = 
  struct
    let arg x = fun y rest -> rest (OP.op x y) ;;
    let stop x = x;;
    let f g = g OP.init;;
  end

[-- Attachment #4: Type: TEXT/PLAIN, Size: 132 bytes --]

module ListConcat = struct
  type a and b = a list and c = a list
  let op = fun (x: a) y -> y @ [x] ;;
  let init = [] ;;
end

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

* Re: [Caml-list] with clause
  2011-10-07 16:37 [Caml-list] with clause Walter Cazzola
@ 2011-10-09 15:42 ` Gabriel Scherer
  0 siblings, 0 replies; 2+ messages in thread
From: Gabriel Scherer @ 2011-10-09 15:42 UTC (permalink / raw)
  To: Walter Cazzola; +Cc: OCaML Mailing List

The "with type foo = ..." construct is meant to be used on signatures
(module interfaces), not on structures (module implementations).

First, a remark: if you want to share code, it's not terribly
comfortable if it's split into three different files of five lines
each. You could put your three modules in the same file, and that
would be easier to distribute:

  module type OpVarADT =
   sig
     type a and b and c
     val op: a -> b -> c
     val init : c
   end

  module VarArgs (OP : OpVarADT) =
    struct
      let arg x = fun y rest -> rest (OP.op x y) ;;
      let stop x = x;;
      let f g = g OP.init;;
    end

  module ListConcat = struct
    type a and b = a list and c = a list
    let op = fun (x: a) y -> y @ [x] ;;
    let init = [] ;;
  end

The problem in your code is that, in ListConcat, "type a" is an
abstract type (because it is not of the form "type a =  ...") in an
implementation.
An abstract type in a signature means "there is some concrete
definition that I hide for encapsulation".
An abstract type in an implementation has no definition at all; for
all purposes, it's an unique empty type. You don't have any value of
type `a` and, therefore, you can't use your ListConcat module. You
*can* apply the VarArgs functor to it but the result is useless:

  module M = VarArgs(ListConcat);;

M.arg takes an argument of type ListConcat.a and nobody knows how to
build such a value.

So you were wrong to use an abstract type where in reality you wanted
an parametric type. What you mean is probably something like

  module ListConcat = struct
    type 'a b = 'a list
    ...
  end

However, this is not satisfying as it doesn't respect the OpVarADT
signature, which specifies that the type b is not parametrized. So
with that definition you can't apply VarArgs anymore.

  module ListConcatParam = struct
    type a and 'a b = 'a list and c = a list
    let op = fun (x: a) y -> y @ [x] ;;
    let init = [] ;;
  end

 # module M = VarArgs(ListConcatParam);;
 Type declarations do not match:
    type 'a b = 'a list
  is not included in
     type b
  They have different arities.

So how can you have a type that is somehow parametrized (to be able to
use this ListConcat module with different types of list elements) and
still respect the 0-arity signature ? The answer is the following : if
you can't use parametrized type of the base OCaml language, you can
use the module language to add parametrization, by making your
ListConcat module a functor over a type:

  module ListConcatFunctor (T : sig type t end) = struct
    type a = T.t and b = a list and c = a list
    let op = fun (x: a) y -> y @ [x] ;;
    let init = [] ;;
  end

  module M = VarArgs(ListConcatFunctor(struct type t = int end));;

  # M.f (M.arg 2) (M.arg 3) (M.arg 4) M.stop;;
  - : int list = [2; 3; 4]

It's quite normal you had difficulty with this as a beginner;
combining parametric types and the module systems is one of the most
delicate aspects of the language. Most people don't actually use
functors very often.

On Fri, Oct 7, 2011 at 6:37 PM, Walter Cazzola <cazzola@dico.unimi.it> wrote:
> Dear all,
> I'm still stucked on my example to write a functor for functions with a
> variable number of arguments. In particular I can't instantiate it with
> a generic list ('a list).
>
> Attached you find my code. Sometimes ago some on the list suggested me
> to  use with to specify the value of the generic type (a in my case but
> I can't get rid of its syntax, what I think correct is:
>
>  module M1 = VarArgs(ListConcat with type ListConcat.a = int) ;;
>
> but I get a syntax error on the with.
>
> Please note that I'd like to keep OpVarADT and varargs independent of
> the concrete type of a.
>
> Any help to solve this riddle would be appreciated.
>
> TIA
> Walter
>
> --
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


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

end of thread, other threads:[~2011-10-09 15:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-07 16:37 [Caml-list] with clause Walter Cazzola
2011-10-09 15:42 ` Gabriel Scherer

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