I don&#39;t have an answer to your question, but I asked a similar one a while ago:<div><a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg53872.html">http://www.mail-archive.com/haskell-cafe@haskell.org/msg53872.html</a></div>
<div><br></div><div><a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg53872.html"></a>Ryan Ingram gave an answer:</div><div><a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg53941.html">http://www.mail-archive.com/haskell-cafe@haskell.org/msg53941.html</a></div>
<div><br></div><div>Maybe this helps.</div><div><br></div><div><div class="gmail_quote">On Wed, Oct 7, 2009 at 7:10 AM, Joe Fredette <span dir="ltr">&lt;<a href="mailto:jfredett@gmail.com">jfredett@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">So, I&#39;ve been fiddling with an utterly random idea. What if I had a class:<br>
<br>
    class Hom a b where<br>
              data Rep a b<br>
              hm :: Rep a b -&gt; b<br>
              im  :: a -&gt; Rep a b<br>
<br>
That is, all types that have some conversion between them (an isomorphism originally, then I thought homomorphism, now I&#39;m not sure what the hell I&#39;m talking about, so I&#39;ve just stuck with Hom...) which preserves some sense of &quot;structure&quot; and &quot;content&quot;, for instance<br>

<br>
<br>
     data CouldBe a = Only a | Nada<br>
<br>
is _obviously_ the same type as `Maybe`. However, it can&#39;t be used transparently where `Maybe` can be used. That is, shouldn&#39;t I be able to define a 1-1, onto function `phi :: CouldBe a -&gt; Maybe a` and as such another `pho :: Maybe a -&gt; CouldBe a` such that<br>

<br>
     phi . pho = pho . phi = phum ... errr. `id`?<br>
<br>
Hom a b represents one end of that (specifically `hm . im = phi`, and `hm . im` for the instance `Hom b a` would `pho`), then I could, instead of writing a type which expects maybe, simply expects anything _equivalent_ to a maybe, eg<br>

<br>
     safeHead :: Hom (Maybe a) b =&gt; [c] -&gt; Rep a (Maybe c)<br>
     safeHead [] = im Nothing<br>
     safeHead (x:_) = im (Just x)<br>
<br>
Though- I think this is a little bit off in terms of how it should work, perhaps this is my problem, but the idea is that instead of returning a Maybe, it returns something which can be converted _from_ a maybe. That is, a &quot;generic&quot; type like:<br>

<br>
     data X1 a = X a | Y<br>
<br>
which is the &quot;form&quot; of any &quot;maybe-like&quot; type.<br>
<br>
In one sense, I&#39;m almost trying to be polymorphic over the constructors of a given type, kindof, sortof, if you squint your eyes just right and try not to think too much.<br>
<br>
My problem comes when I try to do this:<br>
<br>
     hom = hm . im<br>
     eq x y = hom x == hom y<br>
<br>
Which, I reason, ought to satisfy the type:<br>
<br>
     eq :: (Hom a b, Eq b) =&gt; a -&gt; a -&gt; Bool<br>
<br>
this assumes that hom defines a equality-preserving conversion. However, the type it infers is:<br>
<br>
    eq :: (Hom a b, Hom a1 b, Eq b) =&gt; a -&gt; a1 -&gt; Bool<br>
<br>
Now, this makes sense, all my signature is is a special case of this type. Interesting consequence, this eq could compare a `Maybe a` and `CouldBe a` in a sensical way. Which is a nice benefit. However, here&#39;s where it gets weird, If I try to _provide_ this signature (the second, more general one, or the first, specific one, it doesn&#39;t matter), GHC gives me the following error:<br>

<br>
Iso.hs:29:10:<br>
    Could not deduce (Hom a b) from the context (Hom a b1, Eq b1)<br>
      arising from a use of `hom&#39; at Iso.hs:29:10-14<br>
    Possible fix:<br>
      add (Hom a b) to the context of the type signature for `eq&#39;<br>
    In the first argument of `(==)&#39;, namely `(hom x)&#39;<br>
    In the expression: (hom x) == (hom y)<br>
    In the definition of `eq&#39;: eq x y = (hom x) == (hom y)<br>
Failed, modules loaded: none.<br>
<br>
for the latter and a similar one (but for each of the `Hom a b`, `Hom a1 b` cases.<br>
<br>
Punchline is this, I&#39;m trying to write a generic equality that works for any two types with the same constructor-structure, when I try to write said function, GHC can infer but not Check (it seems, I&#39;m not sure if that&#39;s the correct lingo) the type...<br>

<br>
My question is twofold.<br>
<br>
1. Is this whole idea even possible? I mean- is there some limitation I&#39;m going to run into, I have run into problems when trying to do:<br>
<br>
    instance (Hom a b, Eq b) =&gt; Eq a where<br>
           blah<br>
<br>
wrt UndecideableInstances. But it seems so _obvious_ what that means, I don&#39;t think I fully understand what&#39;s going on -- that is, whether I&#39;m misunderstanding how class contexts work here, and why this (seemingly obvious) signature is undecidable, or whether I&#39;m just mistaken in my type signature all together. (My goal is to say that anything which can be converted freely to and from something that is an instance of the Eq class, must preserve the equality relationships.<br>

<br>
2. Why is GHC unable to check the types, but infer them. I always understood inferring to be the &quot;hard&quot; part of the problem, and checking to be the &quot;easy&quot; part. Is my intuition wrong?<br>
<br>
I&#39;ve posted the code here[1] for your perusal. It&#39;s not particularly important that I get this solved, it&#39;s just a random idea I wanted to explore and thought the notion might appeal to some other Haskeller&#39;s around there who like to have self-documenting datatypes, but hate having to rewrite lots of simple utility functions as penance for our documentarian sins.<br>

<br>
/Joe<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br></div>