From: "Andreas Rossberg" <AndreasRossberg@web.de>
To: "Jacques Carette" <carette@mcmaster.ca>, <caml-list@inria.fr>
Subject: Re: [Caml-list] Variance problem in higher-order Functors?
Date: Sun, 23 Jul 2006 23:16:16 +0200 [thread overview]
Message-ID: <00ea01c6ae9d$3c459750$15b2a8c0@wiko> (raw)
In-Reply-To: <44C3D4C8.8010502@mcmaster.ca>
"Jacques Carette" <carette@mcmaster.ca> wrote:
> I seem to have encountered a problem in type-checking of higher-order
> functors with type constraints -- it seems to me that the containment
> check is backwards.
Well, yes. That's contravariance.
> (* this works *)
> module type DOMAIN = sig
> type kind
> type foo
> val upd : foo -> foo
> end
>
> type domain_is_field
>
> module Rational = struct
> type kind = domain_is_field
> type foo = int * int
> let upd (x,y) = (x-1, y+1)
> end
>
> module Integer = struct
> type kind
> type foo = int
> let upd x = x-1
> end
>
> module type UPDATE = sig
> type obj
> val update : obj -> obj
> end
>
> module DivisionUpdate(D:DOMAIN with type kind = domain_is_field) = struct
> type obj = D.foo
> let update a = D.upd a
> end
>
> (* this one is semantically incorrect! *)
> module BadUpdate(D:DOMAIN) = struct
> type obj = D.foo
> let update a = D.upd a
> end
>
> (* works, as expected *)
> module A = DivisionUpdate(Rational)
> (* _correctly_ generates an error
> module A = DivisionUpdate(Integer)
> *)
>
> (* However, if we go higher order: *)
> module type UPDATE2 =
> functor(D:DOMAIN) -> sig
> type obj = D.foo
> val update : obj -> obj
> end
>
> (* this is the same as the "updates" above, just wrapped in a module *)
> module Bar(D:DOMAIN)(U:UPDATE2) = 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 does not work?!?! even though it should!*)
> module T2 = Bar(Rational)(DivisionUpdate) ;;
No, it should not work. Bar(Rational) has the signature
functor(U: functor(D:DOMAIN)->S1) -> S2
i.e. argument signature
functor(D:DOMAIN)->S1
but you are trying to apply it to module DivisionUpdate, which has signature
functor(D:DOMAIN')->S1
where DOMAIN'=(DOMAIN with type kind = domain_is_field). This is a
*sub*signature of DOMAIN! Since functors are necessarily contravariant in
their argument, however, it had to be a *super*signature of DOMAIN instead
to allow passing the functor to Bar.
That is, the problem with your example boils down to this:
module type DOMAIN = sig type kind end
module type DOMAIN' = sig type kind = unit end
module Bar (U : functor(D : DOMAIN) -> sig end) = struct end
module Up (D : DOMAIN') = struct end
module T = Bar(Up)
-->
Signature mismatch:
Modules do not match:
functor (D : DOMAIN') -> sig end
is not included in
functor (D : DOMAIN) -> sig end
Modules do not match: DOMAIN is not included in DOMAIN'
Type declarations do not match: type t is not included in type kind = unit
- Andreas
next prev parent reply other threads:[~2006-07-23 21:12 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-23 19:58 Jacques Carette
2006-07-23 21:16 ` Andreas Rossberg [this message]
2006-07-25 20:45 ` How do I achiece this, was Re: [Caml-list] " Jacques Carette
2006-07-26 5:16 ` Jacques Garrigue
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='00ea01c6ae9d$3c459750$15b2a8c0@wiko' \
--to=andreasrossberg@web.de \
--cc=caml-list@inria.fr \
--cc=carette@mcmaster.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox