<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Simon,<div><br></div><div>I’m not sure when this ”feature” was added, but I’m pretty sure that my original implementation of associated types was exactly what you describe in the solution. Or did I miss anything?</div><div><br></div><div>Manuel</div><div><br><div><div>Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com">simonpj@microsoft.com</a>>:</div><blockquote type="cite"><div lang="EN-GB" link="#0563C1" vlink="#954F72" style="font-family: Helvetica; font-size: 16px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="WordSection1" style="page: WordSection1;"><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Friends<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">I want to make withdraw (or, rather, simplify) a little-known feature in GHC, but before I do so I want to check that no one is going to have a heart attack.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Relevant bits of the user manual:<span class="Apple-converted-space"> </span><a href="http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl" style="color: rgb(149, 79, 114); text-decoration: underline;">http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl</a><o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">All of this arose when thinking about fixing Trac #9063.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">I believe that this change will affect essentially nobody, and I propose to implement forthwith in HEAD (and hence 7.10). <o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Does anyone object?<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Thanks<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Simon<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;"> </span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><b><span style="font-size: 16pt;">The issue<o:p></o:p></span></b></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Consider this:<o:p></o:p></span></p><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">class C a where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type T a b :: *<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';"><o:p> </o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">instance C [x] where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type T [x] b = x -> b<o:p></o:p></div><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">That is just what you’d expect.  But currently this is allowed too:<o:p></o:p></span></p><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">instance C [x] where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type T [x] Int = x -> Int<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type T [x] Bool = Bool -> x<o:p></o:p></div><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">That is,<span class="Apple-converted-space"> </span><b>GHC 7.8 allows many associated type instances</b>, provided they don’t overlap.  But, oddly you can’t further instantiate the instance pattern. This would make just as much sense, but isn’t allowed:<o:p></o:p></span></p><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">instance C [x] where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type T [Int] b = b -> Int<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type T [Bool] b = Bool -> b<o:p></o:p></div><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Moreover, as the user manual says, for an open kind like *, none of this really makes sense. It really only makes sense for a closed kind. Something like<o:p></o:p></span></p><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">class D a where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type S (b :: Bool) a :: *<o:p></o:p></div><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">Now<span class="Apple-converted-space"> </span><i>this</i><span class="Apple-converted-space"> </span>would make some kind of sense:<o:p></o:p></span></p><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">instance D [x] where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type S True [x] = x -> x<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type S False [x] = x<o:p></o:p></div><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">But for closed kinds, you really want a<span class="Apple-converted-space"> </span><i>closed</i><span class="Apple-converted-space"> </span>type family.  So this would be better:<o:p></o:p></span></p><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">instance D [x] where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">   type S b [x] = SHelp x b<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';"><o:p> </o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">type family SHelp x b where<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">  SHelp x True = x -> x<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';">  SHelp x False = x<o:p></o:p></div><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 12pt; font-family: 'Courier New';"><o:p> </o:p></div><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">So yes, you do have to declare a named helper type, but you get something much more perspicuous and explicit in exchange.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">All of this also applies to the default declaration(s) which you can supply for an associated type (see 7.7.3.2 in the link above), only it’s a bit more complicated and indirect.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><b><span style="font-size: 16pt;">My solution<o:p></o:p></span></b></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;">I propose to simplify substantially, as follows:<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 36pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: Symbol;"><span>·<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">        <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">The “shared arguments” of an associated type are the argument positions that mention a type variable from the class header.  So in class C above, the first argument position of T is “shared”; and in class D, the second argument position of S is shared.<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 36pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: Symbol;"><span>·<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">        <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">A instance for an associated type (in a class instance declaration) cf 7.7.3.1 must have<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 72pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: 'Courier New';"><span>o<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">  <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">type variables in the non-shared argument positions, and<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 72pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: 'Courier New';"><span>o<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">  <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">an exact copy of the corresponding instance header type in the shared positions<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 36pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: Symbol;"><span>·<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">        <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">For each associated type you can have<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 72pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: 'Courier New';"><span>o<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">  <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">at most one default declaration in the class declaration<o:p></o:p></span></p><p class="MsoListParagraph" style="margin: 6pt 0cm 6pt 72pt; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: -18pt;"><span style="font-size: 12pt; font-family: 'Courier New';"><span>o<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">  <span class="Apple-converted-space"> </span></span></span></span><span style="font-size: 12pt;">at most one type instance declaration in the class instance declaration<o:p></o:p></span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;"> </span></p><p class="MsoNormal" style="margin: 6pt 0cm; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-size: 12pt;"> </span></p></div>_______________________________________________<br>ghc-devs mailing list<br><a href="mailto:ghc-devs@haskell.org" style="color: rgb(149, 79, 114); text-decoration: underline;">ghc-devs@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/ghc-devs" style="color: rgb(149, 79, 114); text-decoration: underline;">http://www.haskell.org/mailman/listinfo/ghc-devs</a></div></blockquote></div><br></div></body></html>