<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:12.0pt;
        font-family:"Times New Roman",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:12.0pt;
        font-family:"Times New Roman",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"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">If you are thinking about the compiler internals, then knowing about State# etc is necessary.   “</span><span style="font-size:9.5pt">Digging it up in the compiler
 is hard</span><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">”  Indeed, and you should not have to do that.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">If you are think about
<i>programmers</i>, and how they <i>reason about their programs</i>, then my working hypothesis is that all that stuff should be irrelevant, and indeed confusing.  State# etc is just an implementation technique.  Just use the semantics in “Tackling the awkward
 squad”.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Simon<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><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" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> ghc-devs [mailto:ghc-devs-bounces@haskell.org]
<b>On Behalf Of </b>Christopher Allen<br>
<b>Sent:</b> 31 January 2016 01:57<br>
<b>To:</b> ghc-devs@haskell.org<br>
<b>Subject:</b> Nailing down what we expect IO to do and not do - and why<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">
<span style="font-size:9.5pt">I'm writing a book, I'd like to get this nailed down and to get it right. If anyone on here that's familiar with the various ways in which IO/State#/realWorld# work in GHC and you have time to reply, anything at all would be welcome. Any
 pointers, links, references, details, anecdotes, or faint memories of GHC bugs will be greatly appreciated! Getting this written up (possibly for addition to Michael Snoyman's wiki article?) would make me, and I imagine others, a lot happier with trying to
 understand how the different bits and bobs fit together.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">I will be dumping my notes as I don't want to get linked to stuff that can be googled because I've already lost 10-15 hours to just that in the past 3-4 days. Digging it up in the compiler is hard because compiler behavior that
 influences how IO actions are treated don't necessarily have "IO" or "realWorld" mentioned in the relevant parts of the compiler, optimizations, etc.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">What I'm hoping for is answers on what specifically preserves the listed properties we want from IO in the compiler, prims, or structure of how we write IO actions.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">What we expect IO to do:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Disable sharing of results, even when it's not a lambda and is evaluated multiple times by the same name. ie, getCurrentTime :: IO UTCTime   should get evaluated more than once.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Not reorder sequential IO actions, such as in a do-block. Called "linearity" below<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Not duplicate the effects of IO actions. Effects shouldn't be spuriously duplicated during optimization passes.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Effects should not be discarded separately of the value returned by an IO action, merged, or elided.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"># Sharing</span><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">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">A friend suggested that perhaps one-shot semantics via the state hack for State# in the IO type is responsible for disabling sharing, I don't believe so, but here are my notes.<o:p></o:p></span></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>-fno-state-hack<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>Turn off the "state hack" whereby any lambda with a State# token as argument is considered to be single-entry, hence it is considered OK to inline things inside it. This can improve performance of IO and ST monad code, but it
 runs the risk of reducing sharing.<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>A one shot lambda <o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>State hack, makes the lambda over State# assume it's one-shot universally by default.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>one-shot/state hack is an anti-inlining heuristic, suggesting that inlining is costly.<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Also I found this on Trac, does anyone know the answer to this? Is the summary above accurate?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>Can the IO state hack be avoided if oneShot is used in the right places in library code, e.g. in IO’s definition of >>=?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">This seems related how the state token works, for differentiating which IO action is which and how many times an IO action should run, when it should run, etc.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">From the prims:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>data State# s<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>State# is the primitive, unlifted type of states. It has one type parameter, thus State# RealWorld, or State# s, where s is a type variable. The only purpose of the type parameter is to keep different state threads separate. It
 is represented by nothing at all.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>data RealWorld<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">>RealWorld is deeply magical. It is primitive, but it is not unlifted (hence ptrArg). We never manipulate values of type RealWorld; it's only used in the type system, to parameterise State#.<o:p></o:p></span></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"># Linearity<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Is this from the nesting of lambdas? It doesn't seem like that's enough based on the various examples using State/State# in GHC Trac bug tickets. The RealWorld token seems to be what's driving this but precisely how that works
 hasn't been easy to find.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"># Discarding, not inlining effects<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">I believe these are addressed by has_side_effects in the prim ops. I could very well be wrong.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">            can_fail     has_side_effects<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Discard        NO            NO<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Float in       YES           YES<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Float out      NO            NO<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Duplicate      YES           NO<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">* Duplication.  You cannot duplicate a has_side_effect primop.  You<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">  might wonder how this can occur given the state token threading, but<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">  just look at Control.Monad.ST.Lazy.Imp.strictToLazy!  We get<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">  something like this<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">        p = case readMutVar# s v of<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">              (# s', r #) -> (S# s', r)<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">        s' = case p of (s', r) -> s'<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">        r  = case p of (s', r) -> r<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><br>
I believe duplication addresses inlining IO actions more generally but I could be wrong. Here's a note I found regarding elision/merging:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">  * Use the compiler flag @-fno-cse@ to prevent common sub-expression<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">        elimination being performed on the module, which might combine<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">        two side effects that were meant to be separate.  A good example<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">        is using multiple global variables (like @test@ in the example below).<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Any help or pointers for nailing down and documenting this would be greatly appreciated. Also if there's a more detailed explanation of what behavior is expected out of each unsafe function, that would help as well. There are bits
 and pieces I've been able to aggregate from the GHC trac tickets.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">References used (not exhaustive):<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Referential Transparency; Haskell Wiki<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><a href="https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fwiki.haskell.org%2fReferential_transparency&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c8f855b4f9a8b425f1e3d08d329e1d18d%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=ecpPX5Ru1ov20MumzpjiSHEX5uR12Xyk1CaHQ0Vizcw%3d" target="_blank">https://wiki.haskell.org/Referential_transparency</a><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- IO Inside; Haskell Wiki<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><a href="https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fwiki.haskell.org%2fIO_inside&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c8f855b4f9a8b425f1e3d08d329e1d18d%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=fk7unq7EtFReU81Td%2bvhAYAFE71hzTLcoCuM4SJz90s%3d" target="_blank">https://wiki.haskell.org/IO_inside</a><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Unraveling the mystery of the IO Monad; Edward Z. Yang<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fblog.ezyang.com%2f2011%2f05%2funraveling-the-mystery-of-the-io-monad%2f&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c8f855b4f9a8b425f1e3d08d329e1d18d%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=sUe0aq9yaMNqNzhlEOporHOLgBkDWF3t27HOhrq7MmQ%3d" target="_blank">http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/</a><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Evaluation order and state tokens; Michael Snoyman<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><a href="https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fwiki.haskell.org%2fEvaluation_order_and_state_tokens&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c8f855b4f9a8b425f1e3d08d329e1d18d%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=SO1OefBi8YlTWj3vDq8pbwupW3LFGMsf2hGyXwPQ6O0%3d" target="_blank">https://wiki.haskell.org/Evaluation_order_and_state_tokens</a><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Haskell GHC Illustrated; Takenobu Tani<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Tackling the Awkward Squad; Simon Peyton Jones<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fresearch.microsoft.com%2fen-us%2fum%2fpeople%2fsimonpj%2fpapers%2fmarktoberdorf%2fmark.pdf&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c8f855b4f9a8b425f1e3d08d329e1d18d%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=0V9ZswJSVeZfZR1i0Qn7wORO8f7Qd1geUJap0e8hCKQ%3d" target="_blank">http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/mark.pdf</a><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Note [IO hack in the demand analyser]; GHC source code<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Monadic I/O in Haskell 1.3; Andrew D. Gordon and Kevin Hammond<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">- Haskell Report 1.2<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fhaskell.cs.yale.edu%2fwp-content%2fuploads%2f2011%2f01%2fhaskell-report-1.2.pdf&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c8f855b4f9a8b425f1e3d08d329e1d18d%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=SrvFhhQkvW%2f%2f1PFcpV8VKSaEeqrfm53JfUFJdUnXeWA%3d" target="_blank">http://haskell.cs.yale.edu/wp-content/uploads/2011/01/haskell-report-1.2.pdf</a><o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Thank you for your time,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-size:9.5pt">Chris<o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</body>
</html>