<div dir="ltr">I have a trick that loses a little convenience, but may still be more convenient than data families.<div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div style><font face="courier new, monospace">{-# LANGUAGE TypeFamilies #-}</font></div>

<div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">import Data.Tagged</font></div><div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">type family F a</font></div>

<div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">foo :: Tagged a (F a)</font></div><div style><font face="courier new, monospace">foo = Tagged undefined</font></div>

<div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">bar :: Tagged a (F a)</font></div><div style><font face="courier new, monospace">bar = foo</font></div></blockquote>

<div style><br></div><div style>This allows you to use the same newtype wrapper consistently, regardless of what the type instance actually is; one of the inconveniences of data families is the need to use different constructors for different types.</div>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 13, 2013 at 2:10 PM, Conal Elliott <span dir="ltr">&lt;<a href="mailto:conal@conal.net" target="_blank">conal@conal.net</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I sometimes run into trouble with lack of injectivity for type families. I&#39;m trying to understand what&#39;s at the heart of these difficulties and whether I can avoid them. Also, whether some of the obstacles could be overcome with simple improvements to GHC.<br>



<br>Here&#39;s a simple example:<br><br>&gt; {-# LANGUAGE TypeFamilies #-}<br>&gt;<br>&gt; type family F a<br>&gt;<br>&gt; foo :: F a<br>&gt; foo = undefined<br>&gt;<br>&gt; bar :: F a<br>&gt; bar = foo<br><br>The error message:<br>



<br>    Couldn&#39;t match type `F a&#39; with `F a1&#39;<br>    NB: `F&#39; is a type function, and may not be injective<br>    In the expression: foo<br>    In an equation for `bar&#39;: bar = foo<br><br>A terser (but perhaps subtler) example producing the same error:<br>



<br>&gt; baz :: F a<br>&gt; baz = baz<br><br>Replacing `a` with a monotype (e.g., `Bool`) eliminates the error.<br><br>Does the difficulty here have to do with trying to *infer* the type and then compare with the given one? Or is there an issue even with type *checking* in such cases?<br>



<br>Other insights welcome, as well as suggested work-arounds.<br><br>I know about (injective) data families but don&#39;t want to lose the convenience of type synonym families.<br><br>Thanks,  -- Conal<br><br></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">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>
<br></blockquote></div><br></div>