Mkay. I get it now. I was under the impression that, essentially, a data family was precisely equivalent to a type family aliasing to a separately declared datatype.<br><br>One more question: is there any way to get the low overhead of newtypes for particular instances of a data family? Is this impossible? That is, is there any way to do something like<br>
<br>data family Foo a<br>data instance Foo Int = Bar Int -- Bar is actually a newtype<br><br clear="all">Louis Wasserman<br><a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a><br>
<br><br><div class="gmail_quote">On Thu, Apr 2, 2009 at 12:47 PM, David Menendez <span dir="ltr"><<a href="mailto:dave@zednenem.com">dave@zednenem.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
2009/4/2 Louis Wasserman <<a href="mailto:wasserman.louis@gmail.com">wasserman.louis@gmail.com</a>>:<br>
<div class="im">> Mkay. One more quick thing -- the wiki demonstrates a place where the<br>
> original attempt worked, with a data family instead. (That is, replacing<br>
> 'type' with 'data' and adjusting the instance makes this program compile<br>
> immediately.)<br>
> a) Is there a type-hackery reason this is different from data families?<br>
<br>
</div>It's not type hackery. Data families are different from type families,<br>
and the syntax for declaring instances of higher-kinded families is a<br>
consequence of those differences.<br>
<br>
An instance of a data family is a new type constructor, so you have to<br>
provide the additional arguments in order to declare the data<br>
constructors.<br>
<br>
data family Foo a :: * -> *<br>
data instance Foo Bool a = FB a a<br>
-- Foo Bool has kind * -> *, like [], so I could make it a Functor<br>
<br>
Instance of type families are always pre-existing type constructors.<br>
<br>
type family Bar a :: * -> * -- Bar a must equal something of kind * -> *<br>
type instance Bar () = Maybe<br>
<div class="im"><br>
> b) Is there a reason this isn't made a lot clearer in the documentation?<br>
> GHC's docs say that higher-order type families can be declared with kind<br>
> signatures, but never gives any examples -- which would make it a lot<br>
> clearer that the below program doesn't work.<br>
<br>
</div>Here's a higher-kinded type family I've used.<br>
<br>
type family Sig t :: * -> *<br>
<br>
class (Traversable (Sig t)) => Recursive t where<br>
roll :: Sig t t -> t<br>
unroll :: t -> Sig t t<br>
<br>
<br>
The Traversable context wouldn't be valid if I had declared Sig t a ::<br>
*, because type families must always be fully applied.<br>
<br>
<br>
The difference is analogous to the difference between<br>
<br>
type M0 a = StateT Int IO a<br>
type M1 = StateT Int IO<br>
<br>
Since type synonyms (like type and data families) must always be fully<br>
applied, you can use M1 in places where you can't use M0, even though<br>
they're effectively the same thing.<br>
<br>
foo :: ErrorT String M1 a -- valid<br>
bar :: ErrorT String M0 a -- not valid<br>
<font color="#888888"><br>
<br>
<br>
--<br>
Dave Menendez <<a href="mailto:dave@zednenem.com">dave@zednenem.com</a>><br>
<<a href="http://www.eyrie.org/%7Ezednenem/" target="_blank">http://www.eyrie.org/~zednenem/</a>><br>
</font></blockquote></div><br>