On 8/1/07, apfelmus &lt;<a href="mailto:apfelmus@quantentunnel.de">apfelmus@quantentunnel.de</a>&gt; wrote:<br><br>&gt; There are some fundamental problems/design choices for type classes<br>&gt; in conjunction with separate compilation/modularity that need to be
<br>&gt; researched before trying anything like that. In particular, any<br>&gt; ad-hoc Prolog, CHR or -fallow-undecidable-instances just ignores<br>&gt; these problems and doesn&#39;t solve them.<br><br>&gt; The problem with the Functor/Cofunctor instances is that they are
<br>&gt; ambiguous as soon as a type constructor X is made an instance of<br>&gt; both Functor and Cofunctor . Of course, such an X cannot exist in a<br>&gt; mathematically useful way (really ?) but the current system doesn&#39;t
<br>&gt; allow to tell this to the compiler. Alas, we can always say<br><br>&gt;&nbsp;&nbsp; instance Functor F where<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; fmap&nbsp;&nbsp; = undefined<br>&gt;&nbsp;&nbsp; instance Cofunctor F where<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; cofmap = undefined<br><br>&gt; The problem is not so much that there might be ambiguities, but how
<br>&gt; to detect and when to report them.<br><br>I agree: and my intent is that the compiler would detect and report the ambiguity as an error.<br><br>&gt;&nbsp;&nbsp;&nbsp; Consider:<br><br>&gt;&nbsp;&nbsp; module F where<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; class Functor f
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; class Cofunctor f<br><br>&gt;&nbsp;&nbsp; module O where<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; import F<br><br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; data O f g a<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; instance (Functor g,&nbsp;&nbsp; Functor f&nbsp; ) =&gt; Functor (O g f)<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; instance (Cofunctor g, Cofunctor f) =&gt; Functor (O g f)
<br><br>&gt;&nbsp;&nbsp; module X where<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; import F<br><br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; data X a<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; instance Functor&nbsp;&nbsp; X<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; instance Cofunctor X<br><br>&gt;&nbsp;&nbsp; module Unsound where<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; import F<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; import O<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; import X<br><br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; type Unsound a = O X X a<br><br>&gt; The current design rejects module O.<br>&gt; - Another possible design choice is to reject only module Unsound, i.e.<br>&gt; when the conflicting instance declarations both come into scope. But it
<br>&gt; may be tricky/undecidable to to detect such conflicting instances.<br>&gt; - A third possibility is to reject module X based on hypothetical<br>&gt; information from module F that states that the instances of Functor and
<br>&gt; Cofunctor are disjoint.<br>&gt; - The fourth choice is to not reject any module but to wait until a<br>&gt; function really uses the type&nbsp; Unsound a&nbsp; and to reject this function.<br>&gt; This is probably a bad idea since this may delay the error even further
<br>&gt; to modules that import Unsound.<br><br>I&#39;d be much happier with any of the latter three options than with the current design.<br><br>&nbsp; - Conal<br><br>