<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 12 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Verdana;
        panose-1:2 11 6 4 3 5 4 4 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.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Plain Text Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Verdana","sans-serif";}
span.PlainTextChar
        {mso-style-name:"Plain Text Char";
        mso-style-priority:99;
        mso-style-link:"Plain Text";
        font-family:"Verdana","sans-serif";}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 90.0pt 72.0pt 89.95pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1270551720;
        mso-list-type:hybrid;
        mso-list-template-ids:981605524 134807553 134807555 134807557 134807553 134807555 134807557 134807553 134807555 134807557;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l1
        {mso-list-id:1288972059;
        mso-list-type:hybrid;
        mso-list-template-ids:-2063070768 134807553 134807555 134807557 134807553 134807555 134807557 134807553 134807555 134807557;}
@list l1:level1
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l1:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></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="MsoPlainText">Good stuff.&nbsp; The basic idea seems good to me.<o:p></o:p></p>
<p class="MsoPlainText"><o:p>&nbsp;</o:p></p>
<p class="MsoPlainText">I'm not sure that a plugin is the way to go here, though it's a good start.&nbsp;
<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span style="font-family:Symbol"><span style="mso-list:Ignore">·<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>Exactly which programs are type-correct?&nbsp; Eg<br>
&nbsp;&nbsp;&nbsp; coerce (listNT createNT)<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt">It all depends on exactly what type args createNT is applied to.<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span style="font-family:Symbol"><span style="mso-list:Ignore">·<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>A function f = createNT probably would not be accepted.&nbsp; But if ‘f’ was inlined sufficiently early (before the plugin) it might.<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span style="font-family:Symbol"><span style="mso-list:Ignore">·<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>Giving an error message in terms of exactly the text the user wrote is harder.<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo1">
<![if !supportLists]><span style="font-family:Symbol"><span style="mso-list:Ignore">·<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>I’m not sure how you expect to deal with essential NT arguments:<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt">newtype T a = MkT a a<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt">tNT :: NT a b -&gt; NT (T a) (T b)<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt">tNT n = createNT ???<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt"><o:p>&nbsp;</o:p></p>
<p class="MsoPlainText">On the whole I think a ‘deriving’ form would be preferable.&nbsp; And then yes, you’ll need to build HEAD.<o:p></o:p></p>
<p class="MsoPlainText"><o:p>&nbsp;</o:p></p>
<p class="MsoPlainText">To your questions:<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo2">
<![if !supportLists]><span style="font-family:Symbol"><span style="mso-list:Ignore">·<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>To do these kind of things, CoreM will need more reader stuff.&nbsp; In particular:<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt;text-indent:-18.0pt;mso-list:l1 level2 lfo2">
<![if !supportLists]><span style="font-family:&quot;Courier New&quot;"><span style="mso-list:Ignore">o<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;
</span></span></span><![endif]>The global TypeEnv<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt;text-indent:-18.0pt;mso-list:l1 level2 lfo2">
<![if !supportLists]><span style="font-family:&quot;Courier New&quot;"><span style="mso-list:Ignore">o<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;
</span></span></span><![endif]>The GlobalRdrEnv<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:36.0pt;text-indent:-18.0pt;mso-list:l1 level1 lfo2">
<![if !supportLists]><span style="font-family:Symbol"><span style="mso-list:Ignore">·<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>I don’t think we have generic Core traversal functions, perhaps because almost every such pass needs to deal with binders.<o:p></o:p></p>
<p class="MsoPlainText"><o:p>&nbsp;</o:p></p>
<p class="MsoPlainText">Simon<o:p></o:p></p>
<p class="MsoPlainText" style="margin-left:72.0pt"><o:p>&nbsp;</o:p></p>
<p class="MsoPlainText"><o:p>&nbsp;</o:p></p>
<p class="MsoPlainText">|&nbsp; <span lang="EN-US">-----Original Message-----</span></p>
<p class="MsoPlainText">|&nbsp; <span lang="EN-US">From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-</span></p>
<p class="MsoPlainText">|&nbsp; <span lang="EN-US">bounces@haskell.org] On Behalf Of Joachim Breitner</span></p>
<p class="MsoPlainText">|&nbsp; <span lang="EN-US">Sent: 01 July 2013 13:00</span></p>
<p class="MsoPlainText">|&nbsp; <span lang="EN-US">To: glasgow-haskell-users@haskell.org</span></p>
<p class="MsoPlainText">|&nbsp; <span lang="EN-US">Subject: Exposing newtype coercions to Haskell</span></p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; Hi,</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; this is related to</p>
<p class="MsoPlainText">|&nbsp; http://hackage.haskell.org/trac/ghc/wiki/NewtypeWrappers#Proposal3.</p>
<p class="MsoPlainText">|&nbsp; I tried to hack up a little prototype of this, and this “works” now:</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;import GHC.NT</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newtype Age = Age Int deriving Show</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ageNT :: NT Age Int</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ageNT = createNT</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newtype MyList a = MyList [a] deriving Show</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myListNT :: NT (MyList a) [a]</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myListNT = createNT</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;main = do</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let n = 1 :: Int</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let a = coerce (sym ageNT) 1</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let l1 = [a]</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let l2 = coerce (listNT ageNT) l1</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let l3 = coerce (sym myListNT) l2</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print a</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print l2</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print l3</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; will print</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Age 1</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[1]</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyList [1]</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; and no unsafeCoerce and no map is used in the production of this output.</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; The GHC.NT module provides:</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; data NT a b</p>
<p class="MsoPlainText">|&nbsp; coerce :: NT a b -&gt; a -&gt; b</p>
<p class="MsoPlainText">|&nbsp; refl&nbsp;&nbsp; :: NT a a</p>
<p class="MsoPlainText">|&nbsp; sym&nbsp;&nbsp;&nbsp; :: NT a b -&gt; NT b a</p>
<p class="MsoPlainText">|&nbsp; trans&nbsp; :: NT a b -&gt; NT b c -&gt; NT a c</p>
<p class="MsoPlainText">|&nbsp; createNT :: NT a b</p>
<p class="MsoPlainText">|&nbsp; listNT :: NT a b -&gt; NT [a] [b]</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; where createNT takes the place of the &quot;deriving foo :: NT a b&quot; syntax:</p>
<p class="MsoPlainText">|&nbsp; At compile time, it is checked if its first type argument is a newtype of the second,</p>
<p class="MsoPlainText">|&nbsp; and the corresponding coercion is inserted, otherwise an error is (well, will be)</p>
<p class="MsoPlainText">|&nbsp; printed.</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; The idea is that these coercions will be guaranteed to be free (or almost free; I am</p>
<p class="MsoPlainText">|&nbsp; not sure if the coercion witness (NT a b) will actually be optimized away).</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; The prototype can be found at</p>
<p class="MsoPlainText">|&nbsp; https://github.com/nomeata/nt-coerce</p>
<p class="MsoPlainText">|&nbsp; and is implemented as a GHC plugin compatible with GHC 7.6.3 (I chose this</p>
<p class="MsoPlainText">|&nbsp; route as it means not having to compile GHC). You can check if it works for you via</p>
<p class="MsoPlainText">|&nbsp; $ ghc&nbsp; -dcore-lint -package ghc --make test.hs&nbsp; &amp;&amp; ./test</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; The code itself is, well, at most prototype code quality and contains quite a</p>
<p class="MsoPlainText">|&nbsp; number of hacks and other warts, mostly due to my inexperience with GHC</p>
<p class="MsoPlainText">|&nbsp; hacking, and I could make use of some advice. Some more concrete questions:</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;* How do I look up a module (here GHC.NT.Type) and a name therein (NT) in</p>
<p class="MsoPlainText">|&nbsp; CoreM? I tried to go via getOrigNameCache, but passing the ModuleName name to</p>
<p class="MsoPlainText">|&nbsp; lookupModuleEnv yielded Nothing, although it seems to me to be precisely the</p>
<p class="MsoPlainText">|&nbsp; same name that I find in moduleEnvKeys. If I take the ModuleName from that list,</p>
<p class="MsoPlainText">|&nbsp; it works. Similar problems with the OccEnv.</p>
<p class="MsoPlainText">|&nbsp; Please see</p>
<p class="MsoPlainText">|&nbsp; https://github.com/nomeata/nt-</p>
<p class="MsoPlainText">|&nbsp; coerce/blob/edef9f4d4889dde651bb086e76c576f84e8f8aec/GHC/NT/Plugin.hs#L9</p>
<p class="MsoPlainText">|&nbsp; 9</p>
<p class="MsoPlainText">|&nbsp; for what I tried (and how I worked around it). This work-around also prevents</p>
<p class="MsoPlainText">|&nbsp; building the package with cabal right now.</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;* I did not find generic Core traversal functions like traverse :: (Monad m) =&gt;</p>
<p class="MsoPlainText">|&nbsp; (Expr a -&gt; m (Maybe (Expr a))) -&gt; Expr a -&gt; m (Expr a) which&nbsp; I defined in</p>
<p class="MsoPlainText">|&nbsp; https://github.com/nomeata/nt-</p>
<p class="MsoPlainText">|&nbsp; coerce/blob/edef9f4d4889dde651bb086e76c576f84e8f8aec/GHC/NT/Plugin.hs#L2</p>
<p class="MsoPlainText">|&nbsp; 31.</p>
<p class="MsoPlainText">|&nbsp; Are such traversals re-implemented everywhere or did I just not search well</p>
<p class="MsoPlainText">|&nbsp; enough?</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; &nbsp;* On the core level, once I have a TyCon, I also have all DataCons available. Is</p>
<p class="MsoPlainText">|&nbsp; there already code present that checks if the currently compiled module really</p>
<p class="MsoPlainText">|&nbsp; should see the data constructors, i.e. if they are exported? I see code in</p>
<p class="MsoPlainText">|&nbsp; normaliseFfiType, but that seems to be integrated in the type checker, and it</p>
<p class="MsoPlainText">|&nbsp; seems I need a GlobalRdrEnv; can I get such a thing in a Core2Core pass?</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; Thanks,</p>
<p class="MsoPlainText">|&nbsp; Joachim</p>
<p class="MsoPlainText">|&nbsp; </p>
<p class="MsoPlainText">|&nbsp; --</p>
<p class="MsoPlainText">|&nbsp; Joachim “nomeata” Breitner</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;mail@joachim-breitner.de • http://www.joachim-breitner.de/</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;Jabber: nomeata@joachim-breitner.de&nbsp; • GPG-Key: 0x4743206C</p>
<p class="MsoPlainText">|&nbsp; &nbsp;&nbsp;Debian Developer: nomeata@debian.org</p>
</div>
</body>
</html>