<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><div>(I'm using a fixed width font, so if you don't see nice formatting, you need to use a fixed width font. &nbsp;This is literate Haskell, but I copied and pasted the code. &nbsp;YMMV)</div><div><br></div>Hi Everybody!&nbsp;(Hi Dr. Nick)</span></font><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">I've been looking for a good way to use some richer notions of polymorphism than Haskell98 allows. &nbsp;</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">First, I tried to define a monad "of" the things I want to quantify over (so each "type of view" or "type of evaluable thing" would be a constructor in a monadic type.) &nbsp;But that didn't seem to offer the kind of extensibility I wanted, since I basically want to join several types together. &nbsp;I tried FunDeps next, and that worked okay, but it was a bit difficult to keep track of what was "meant" to do what. &nbsp;I guess I could have plowed through the work, but it wasn't any fun.</span></font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">I finally heard about TypeFamilies, and they seem to give me the kind of extensibility I want, while keeping the theoretical foundations relatively clean.</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">But I am not so sure I understand them. &nbsp;Let us consider the code:</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; type AbstractValue = Int</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; class Evaluate asset where</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp;data Value asset :: *</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp;value :: (Value asset) -&gt; AbstractValue</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">That's easy enough. &nbsp;"Value asset" is an indexed type. &nbsp;That is reflected in the instance declaration:</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; instance Evaluate Abstract where</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp;data Value Abstract = AbstractValue Abstract</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp;value (AbstractValue int) = int</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Okay, easy enough. &nbsp;But what&nbsp;happens&nbsp;when&nbsp;we&nbsp;want&nbsp;to&nbsp;"add"&nbsp;Evaluate&nbsp;instances?</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt;&nbsp;data&nbsp;Add&nbsp;a&nbsp;b&nbsp;=&nbsp;Add&nbsp;a&nbsp;b</span></font></div><div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; instance ( Evaluate a</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;, Evaluate b</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;) =&gt; Evaluate (Add a b) where</span></font></div><div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;data Value (Sum a b) = SumValue (Sum a b)</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Even this much is straightforward. &nbsp;We require a and b to be Evaluate'able before we can find the sum of a and b as "values". &nbsp;Now I want to write my definition for the "value" function. &nbsp;But... how is that supposed to work? &nbsp;My first guess is</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">value (SumValue (Sum a b)) = (value a) + (value b)</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">But I more-or-less expected that to fail. &nbsp;I realize I need some more typing information. &nbsp;What am I supposed to fill in? &nbsp;My next guess was</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">&gt; <span class="Apple-tab-span" style="white-space:pre">        </span>&nbsp;&nbsp;&nbsp;value (SumValue (Sum a b)) = (value $ Value a) + (value $ Value b)</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">But Value doesn't exist as a type constructor. &nbsp;So now that I am starting to "get" what's going on, I wonder why I don't get what's going on. &nbsp;Since I need to use a type constructor for the (Value a) and (Value b) "things", it kind of defeats the point. &nbsp;(I hesitate to say "value", since I have been using "value" to mean the result/blah of an Evaluate instance)</span></font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Speaking&nbsp;of&nbsp;which,&nbsp;I&nbsp;am&nbsp;still&nbsp;not&nbsp;sure&nbsp;what&nbsp;the&nbsp;difference&nbsp;between&nbsp;associate&nbsp;data&nbsp;type&nbsp;families&nbsp;and&nbsp;associated&nbsp;type&nbsp;constructor&nbsp;families&nbsp;are.&nbsp;&nbsp;The&nbsp;former&nbsp;use&nbsp;the&nbsp;data&nbsp;keyword&nbsp;in&nbsp;class&nbsp;declarations,&nbsp;and&nbsp;the&nbsp;latter&nbsp;use&nbsp;type&nbsp;keywords. &nbsp;What can I do with one and not the other?</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">I&nbsp;would&nbsp;really&nbsp;appreciate&nbsp;some&nbsp;guidance. &nbsp;</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Thanks!</span></font></div><div><font class="Apple-style-span" face="Courier" size="3"><span class="Apple-style-span" style="font-size: 12px;">Alex</span></font></div></div></div></body></html>