<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.Code, li.Code, div.Code
        {mso-style-name:Code;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:9.0pt;
        font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;
        font-weight:normal;
        font-style:normal;
        text-decoration:none none;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
.MsoPapDefault
        {mso-style-type:export-only;
        margin-top:6.0pt;
        margin-right:0cm;
        margin-bottom:6.0pt;
        margin-left:0cm;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal" style="margin-left:36.0pt">I believe you are in luck. Since 7.8.1, GHC supports "unidirectional pattern synonyms<span style="font-size:12.0pt">
<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Yes, but a pattern synonym is a bit of heavyweight way to expose a data constructor for pattern matching but not for construction.  The latter seems simpler somehow.  I’ve wanted this too.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">And yet, and yet, it’s one more piece of complexity, at least the export list (and maybe an import list too!). 
<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">And someone is sure to want to export it for construction but not pattern matching :-).  For that we routinely make a term-level function for construction and don’t export the constructor at all.  The pattern
 synonym is the natural dual of this. <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">TL;DR: you can do both today but you have to write some boilerplate. Whether it’s worth abbreviating I’m not sure.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Simon<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span lang="EN-US"> Libraries <libraries-bounces@haskell.org>
<b>On Behalf Of </b>Bryan Richter<br>
<b>Sent:</b> 22 February 2019 05:29<br>
<b>To:</b> Levent Erkok <erkokl@gmail.com><br>
<b>Cc:</b> libraries@haskell.org<br>
<b>Subject:</b> Re: qualified exports , what would that mean Re: Add<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
> A<span style="font-family:"Arial",sans-serif">nother pet peeve: Export constructors but only for pattern matching purposes, i.e., elimination; not for construction--we'd export smart constructors for the latter which would ensure invariants</span><br>
<br>
I believe you are in luck. Since 7.8.1, GHC supports "unidirectional pattern synonyms", as described somewhere in this section:
<a href="https://nam06.safelinks.protection.outlook.com/?url=https:%2F%2Fdownloads.haskell.org%2F~ghc%2Flatest%2Fdocs%2Fhtml%2Fusers_guide%2Fglasgow_exts.html%23extension-PatternSynonyms&data=02%7C01%7Csimonpj%40microsoft.com%7C8ec7fac7edce4c26f90f08d69886b090%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636864101591212311&sdata=aP6YLYXsNSR0BWc8OEat8fz2yH0asoVFJvq5eh6BPws%3D&reserved=0">
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-PatternSynonyms</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
On Thu, 21 Feb 2019, 23.13 Levent Erkok, <<a href="mailto:erkokl@gmail.com" target="_blank">erkokl@gmail.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
Evan: I liked how you put it: "A bit more finesse on what exactly is imported won't change the basic tradeoff." But still seems to me that Haskells exporting mechanism can be improved. (Another pet peeve: Export constructors but only for pattern matching purposes,
 i.e., elimination; not for construction--we'd export smart constructors for the latter which would ensure invariants. But that's a whole another can of worms.)<o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
I think there's design space here to be explored; in the end, it's the end-users who will have to judge what's useful and what's not.<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
On Thu, Feb 21, 2019 at 12:46 PM Evan Laforge <<a href="mailto:qdunkan@gmail.com" target="_blank">qdunkan@gmail.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
> On Thu, Feb 21, 2019 at 1:42 PM Levent Erkok <<a href="mailto:erkokl@gmail.com" target="_blank">erkokl@gmail.com</a>> wrote:<br>
>><br>
>> I think Carter outlined really good reasons for not including `e`; but it's hard not to sympathize with the request. I often felt shy of adding similar definitions in my libraries for fear that they would pollute the name space. But their absence is rather
 annoying. The classic solution is to put it in a library, internal module etc, and make a new class if necessary; which is often overkill and misses the simplicity sought in the first place.<br>
>><br>
>> I often wonder if Haskell can have a "qualified export" feature for these cases. Just like we can "import qualified," why not "export qualified" some names, which means if you simply import the module the name will still be available qualified. (You can
 of course always import qualified.)<br>
>><br>
>> I haven't thought too much about the implications of this, but it might be an easy solution to this problem. Would love to hear thoughts on this; is there any language that has this feature? How costly would it be to add it to GHC?<br>
<br>
On Thu, Feb 21, 2019 at 11:04 AM Carter Schonwald<br>
<<a href="mailto:carter.schonwald@gmail.com" target="_blank">carter.schonwald@gmail.com</a>> wrote:<br>
><br>
> hey Levent,<br>
> I can't claim to have thought about it that deeply, but naively, it seems like a qualified export approach might not play nice with certain approaches to seperate compilation (not that GHC does it that much), because the names qualifications wouldn't match
 possible import modules, Or at least the qualified names in scope wouldn't match what you see from the import lines, and thus you'd have a harder time supporting good quality error messages? (i could be totally wrong)<br>
><br>
> its definitely an interesting idea, and i certainly dont have clarity on what the implications would be<br>
<br>
If I interpret it correctly, I think what it becomes is that some<br>
symbols can never be imported unqualified.  Or maybe that the default<br>
"import all unqualified" actually means "everything except these<br>
things."  So it would just be an extra rule for what `import` brings<br>
into scope.  Python has such a mechanism, if you have an `__all__ =<br>
[x, y, z]` then `from m import *` will just get you x, y, and z.<br>
<br>
That said, to me it seems like too many ways to do it.  The user can<br>
already get a qualified import if they want it.  When you write an<br>
unqualified "import *", the price you pay is losing control over your<br>
namespace, and that's a known cost.  A bit more finesse on what<br>
exactly is imported won't change the basic tradeoff.<o:p></o:p></p>
</blockquote>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Flibraries&data=02%7C01%7Csimonpj%40microsoft.com%7C8ec7fac7edce4c26f90f08d69886b090%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636864101591212311&sdata=SeCaatfnB8SNvUJIGJRc4PuDGtrf4d5LEyVI1oVJijU%3D&reserved=0" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</body>
</html>