Version française
Home     About     Download     Resources     Contact us    
Browse thread
Variance problem in higher-order Functors?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@m...>
Subject: Re: How do I achiece this, was Re: [Caml-list] Variance problem in higher-order Functors?
From: Jacques Carette <carette@mcmaster.ca>

> In other words, I want to be able to define
> module type Trans = functor(U:UPDATE) ->  functor(D:DOMAIN) -> sig ... end
> but none of my attempts have worked, even though the first-order code 

I think I have a solution, at least to your first post.
If I am right, what you need is to express that Bar's 2nd parameter
is a functor with input of type "DOMAIN with type kind = D.kind".
But you cannot use "with", because the functor type is defined as an
abrreviation. The trick is to wrap the module type definition in a
functor, and to use applicative types.

(* If we go higher order: *)
module UPDATE2(D0:DOMAIN) = struct
  module type S =
    functor(D:DOMAIN with type kind = D0.kind) -> sig
      type obj = D.foo
      val update : obj -> obj
    end
end

(* this is the same as the "updates" above, just wrapped in a module *)
module Bar(D:DOMAIN)(U:UPDATE2(D).S) = struct
    module U = U(D)
    let update x = U.update x
end

(* works as there are no restrictions *)
module T3 = Bar(Integer)(BadUpdate) ;;

(* and now this works! *)
module T2 = Bar(Rational)(DivisionUpdate) ;;

This trick of wrapping module types inside functors proves useful in
many situations, when you want to express sharing that cannot be
expressed by with alone.

Jacques Garrigue