<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Feb 12, 2021, at 5:57 PM, CASANOVA Juan <<a href="mailto:Juan.Casanova@ed.ac.uk" class="">Juan.Casanova@ed.ac.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="caret-color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);" class="">Thanks Richard,<br class=""><br class="">I'll try to stay as short as possible.<br class=""><br class="">"Did you try using the normal pair constructor?"<br class=""><br class="">No, I didn't. I didn't even know it existed. I think now I've seen it before. This is a kind pair, which is different from a pair type, is this correct? So, what I am saying, the ' in the front relevantly changes what it means for the type checker. It's not as simple as using a tuple type (I'm pretty sure I even tried this and the type checker looked at me in confusion).<br class=""></div></div></blockquote><div><br class=""></div><div>I wouldn't call it a kind pair. I think of '(..., ...) just as the normal pair constructor, but used in a type. The reason for the ' is to disambiguate it with (..., ...), which is the type of pairs. It might be helpful to see the kinds of these constructions:</div><div><br class=""></div><div>'(,) :: forall a b. a -> b -> (a, b)</div><div>(,) :: Type -> Type -> Type</div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);" class=""><br class="">I must complain, though, that I've looked for "kind pair Haskell", "type pair Haskell", "multiple kinds Haskell", "tuple kinds Haskell" and "kind tuples Haskell", and found zero references to this particular construct, so I can't really feel like it's my fault for not knowing about it!<br class=""></div></div></blockquote><div><br class=""></div><div>I'm not surprised this information is hard to find. On the one hand, I think the Haskell community (myself included) does a mediocre job of clarifying these sorts of things. On the other, '(,) isn't a special case at all: it behaves in an exactly analogous manner to using any other constructor in a type. (For what it's worth, I don't have a good name for this idea, beyond "the pair constructor used in a type".)</div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);" class=""><br class="">About partial application, you are absolutely right, and I actually knew this, but it sort of went out of my mind when I wrote that. The way that I tend to write Haskell, I do use partial type synonyms quite a bit,<span class="Apple-converted-space"> </span><b class="">and I try to keep type synonyms as high-kinded as possible<i class="">.<span class="Apple-converted-space"> </span></i></b>That is why I forgot about this. So instead of type List a = [a], it's better to use type List = [] because then you can do a lot more with it. But this is besides the point.<br class=""></div></div></blockquote><div><br class=""></div><div>I agree completely that `type List = []` is better than `type List a = [a]`, because the former allows List to be used on its own; the latter would require the argument at all usage sites. It seems you understand this. (Small pointer: I didn't at first understand your meaning from "as high-kinded as possible". I would say "as eta-reduced as possible", but that's perhaps even more opaque if you don't know the term.)</div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);" class=""><br class="">The reasons your solution seems to work and mine doesn't are both the kind pair construct, and the usage of a type family. I've looked into type families before, but never used them in practice, mostly because they didn't actually allow me to do what I looked them up for. This might be the first time that type families are actually the answer for me. I'm still a bit scared of them and not understanding what you can / cannot do with them. This relates to "giving the kind of the result I want": Without type families you cannot do any sort of "computation" at the type level, just syntactic things. I thought this would be enough for Curry / Uncurry, but it obviously isn't.<br class=""></div></div></blockquote><div><br class=""></div><div>The problem is that, for Uncurry, we need to pattern-match on a pair. Pattern-matching requires a type family. Type families are not particularly hard to work with, though: think of them simply as functions written in types. The only "gotcha" is that they always must be saturated.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);" class=""><br class="">In practice, however, this was me trying to save myself some work by implementing a high-level solution that I could reuse several times. When I failed, I wrote the email to try and learn from it, but then moved forward with implementing it in a more mundane way (but more redundant). At this point, I think I'm going to keep going with this implementation. I even think I would not have gotten so much from the curry / uncurry now that I think back. But this was definitely very instructive.<br class=""></div></div></blockquote><div><br class=""></div><div>Glad to be of service!</div><div><br class=""></div><div>Richard</div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);" class=""><br class="">Thanks again.<br class="">Juan.<br class=""><br class=""><br class=""><br class=""><br class=""></div><div id="appendonsend" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div><hr tabindex="-1" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; display: inline-block; width: 801.625px;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class=""></span><div id="divRplyFwdMsg" dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><font face="Calibri, sans-serif" style="font-size: 11pt;" class=""><b class="">From:</b><span class="Apple-converted-space"> </span>Richard Eisenberg <<a href="mailto:rae@richarde.dev" class="">rae@richarde.dev</a>><br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>12 February 2021 20:04<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span>CASANOVA Juan <<a href="mailto:Juan.Casanova@ed.ac.uk" class="">Juan.Casanova@ed.ac.uk</a>><br class=""><b class="">Cc:</b><span class="Apple-converted-space"> </span><a href="mailto:haskell-cafe@haskell.org" class="">haskell-cafe@haskell.org</a><span class="Apple-converted-space"> </span><<a href="mailto:haskell-cafe@haskell.org" class="">haskell-cafe@haskell.org</a>><br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>Re: [Haskell-cafe] Kind pairs and kind currying/uncurrying</font><div class=""> </div></div><div class="" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; word-wrap: break-word; line-break: after-white-space;"><div style="background-color: rgb(255, 242, 230); border: 2px dotted rgb(255, 136, 77);" class=""><span style="font-size: 12pt; font-family: sans-serif; font-weight: bold; padding: 0.2em;" class="">This email was sent to you by someone outside the University.</span><div style="font-size: 10pt; font-family: sans-serif; font-style: normal; padding: 0.2em;" class="">You should only click on links or attachments if you are certain that the email is genuine and the content is safe.</div></div><div class="">Hi Juan,<div class=""><br class=""></div><div class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Feb 12, 2021, at 1:50 PM, CASANOVA Juan <<a href="mailto:Juan.Casanova@ed.ac.uk" class="">Juan.Casanova@ed.ac.uk</a>> wrote:</div><br class="x_Apple-interchange-newline"><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><span class="" style="font-size: 12pt;">The first variation I tried I feel is the most semantically accurate, as it is clear from the beginning of what I am trying to do. The main "insight" I used was using/assuming extensionality of kinds (and partial application of type synonyms) to define a kind pair:</span></div></div></blockquote><blockquote type="cite" class=""><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><div class=""><br class="">type KindPair (a :: ka) (b :: kb) (f :: ka -> kb -> *) = f a b<br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Did you try using the normal pair constructor?</div><div class=""><br class=""></div><div class="">> type KindPair a b = '(a, b)</div><div class=""><br class=""></div><div class="">That would seem to meet your needs, but perhaps I'm missing something.</div><blockquote type="cite" class=""><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><div class=""><br class="">Partial application of type synonyms is fine, I use it all the time. But it seems it is not fine when it is "kind synonyms"??? It is not even asking me for any extension to allow it.<br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Partial application of type synonyms is<span class="Apple-converted-space"> </span><i class="">not</i> fine. Try it out. (GHC does allow this in the definition of other type synonyms, as long as it works out in the end. But it won't work in e.g. type signatures.) I think this is the crux of the problem.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><div class=""><div class="">type KCurry (tf :: (KindPair ka kb) -> kc) = ka -> kb -> kc</div><div class="">type KUncurry (tf :: ka -> kb -> kc) = (KindPair ka kb) -> kc</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">My definitions of these look like this:</div><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">type Curry :: ((a, b) -> c) -> a -> b -> c</div><div class="">type Curry f x y = f '(x, y)</div><div class=""><br class=""></div><div class="">type Uncurry :: (a -> b -> c) -> (a, b) -> c</div><div class="">type family Uncurry f xy where</div><div class=""> Uncurry f '(x, y) = f x y</div></blockquote><div class=""><br class=""></div><div class="">where I've also used -XStandaloneKindSignatures (in GHC 8.10 and up), but you don't need to.</div><div class=""><br class=""></div><div class="">I think part of the problem is that your definitions appear "one level off", unless I'm misunderstanding: you're giving the kind of the result you want, not the actual result you want.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; background-color: rgb(255, 255, 255);"><div class=""><br class=""></div><div class="">Is what I am trying to do completely absurd? I do not think it is, but maybe I am being naive?<br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">No, not absurd. I do think that currying/uncurrying in types is problematic because of the saturation condition on type synonyms and type families. But my guess is that there is a way of addressing your root problem, with class constraints, but I'd need more information to suggest a concrete next step.</div></div><br class=""></div><div class="">I hope this helps!</div><div class="">Richard</div></div></div><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.</span><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">_______________________________________________</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Haskell-Cafe mailing list</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">To (un)subscribe, modify options or view archives go to:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Only members subscribed via the mailman list are allowed to post.</span></div></blockquote></div><br class=""></body></html>