<div dir="ltr"><div><div><div><div><div><div><div><div>With pattern guards, it&#39;s difficult to say whether it is never &#39;useful&#39; to have things like the following work:<br><br></div>    C x | C&#39; y z &lt;- f x = ...<br>
<br></div>But I&#39;d also shy away from changing the behavior because it causes a lot of consistency issues. In<br><br></div>    let<br></div>      f &lt;vs1&gt; | gs1 = es1<br></div>      h &lt;vs2&gt; | gs2 = es2<br></div>
      ...<br><br></div>we have that f and h are in scope in both gs1 and gs2. Does it make sense to call f in gs1? It&#39;s easy to loop if you do. So should f not be in scope in gs1, but h is, and vice versa for gs2? But they&#39;re both in scope for es1 and es2?<br>
<br></div><div>And if we leave the above alone, then what about the case where there are no &lt;vs&gt;? Is that different? Or is it only left-hand patterns that get this treatment?<br><br>Also, it might have some weird consequences for moving code around. Like:<br>
<br></div><div>    let Just x | x &gt; 0 = Just 1<br><br></div><div>    let Just x | y &gt; 0 = Just 1<br></div><div>        y = x<br><br></div><div>    let Just x | b = Just 1<br></div><div>          where b = x &gt; 0<br>
<br></div><div>    let Just x | b = Just 1<br></div><div>        b = x &gt; 0<br></div><div><br></div><div>These all behave the same way now. Which ones should change?<br></div><div><div><div><div><div><div><br></div><div>
If Haskell had a non-recursive let, that&#39;d probably be a different story. But it doesn&#39;t.<br></div><div><br></div></div></div></div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 9, 2013 at 1:12 PM, Andreas Abel <span dir="ltr">&lt;<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks, Dan and Roman, for the explanation.  So I have to delete the explanation &quot;non-recursive let = single-branch case&quot; from my brain.<br>

<br>
I thought the guards in a let are assertations, but in fact it is more like an if.  Ok.<br>
<br>
But then I do not see why the pattern variables are in scope in the guards in<br>
<br>
  let p | g = e<br>
<br>
The variables in p are only bound to their values (given by e) if the guard g evaluates to True.  But how can g evaluate if it has yet unbound variables?  How can ever a pattern variable of p be *needed* to compute the value of the guard?  My conjecture is that it cannot, so it does not make sense to consider variables of g bound by p.  Maybe you can cook up some counterexample.<br>

<br>
I think the pattern variables of p should not be in scope in g, and shadowing free variables of g by pattern variables of p should be forbidden.<br>
<br>
Cheers,<br>
Andreas<br>
<br>
On 09.07.2013 17:05, Dan Doel wrote:&gt; The definition<div class="im HOEnZb"><br>
&gt;<br>
&gt;      Just x | x &gt; 0 = Just 1<br>
&gt;<br></div><div class="im HOEnZb">
&gt; is recursive. It conditionally defines Just x as Just 1 when x &gt; 0 (and<br>
&gt; as bottom otherwise). So it must know the result before it can test the<br>
&gt; guard, but it cannot know the result until the guard is tested. Consider<br>
&gt; an augmented definition:<br>
&gt;<br></div><div class="im HOEnZb">
&gt;      Just x | x &gt; 0  = Just 1<br></div><div class="im HOEnZb">
&gt;             | x &lt;= 0 = Just 0<br>
&gt;<br>
&gt; What is x?<br>
<br></div><div class="HOEnZb"><div class="h5">
On 09.07.2013 17:49, Roman Cheplyaka wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
As Dan said, this behaviour is correct.<br>
<br>
The confusing thing here is that in case expressions guards are attached<br>
to the patterns (i.e. to the lhs), while in let expressions they are<br>
attached to the rhs.<br>
<br>
So, despite the common &quot;Just x | x &gt; 0&quot; part, your examples mean rather<br>
different things.<br>
<br>
Here&#39;s the translation of &#39;loops&#39; according to the Report:<br>
<br>
   loops =<br>
     let Just x =<br>
       case () of<br>
         () | x &gt; 0 -&gt; Just 1<br>
     in x<br>
<br>
Here it&#39;s obvious that &#39;x&#39; is used in the rhs of its own definition.<br>
<br>
Roman<br>
<br>
* Andreas Abel &lt;<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a>&gt; [2013-07-09 16:42:00+0200]<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi, is this a known bug or feature of GHC (7.4.1, 7.6.3)?:<br>
<br>
I got a looping behavior in one of my programs and could not explain<br>
why.  When I rewrote an irrefutable let with guards to use a case<br>
instead, the loop disappeared.  Cut-down:<br>
<br>
   works = case Just 1 of { Just x | x &gt; 0 -&gt; x }<br>
<br>
   loops = let Just x | x &gt; 0 = Just 1 in x<br>
<br>
works returns 1, loops loops.  If x is unused on the rhs, the<br>
non-termination disappears.<br>
<br>
   works&#39; = let Just x | x &gt; 0 = Just 1 in 42<br>
<br>
Is this intended by the Haskell semantics or is this a bug?  I would<br>
have assumed that non-recursive let and single-branch case are<br>
interchangeable, but apparently, not...<br>
<br>
Cheers,<br>
Andreas<br>
<br>
--<br>
Andreas Abel  &lt;&gt;&lt;      Du bist der geliebte Mensch.<br>
<br>
Theoretical Computer Science, University of Munich<br>
Oettingenstr. 67, D-80538 Munich, GERMANY<br>
<br>
<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a><br>
<a href="http://www2.tcs.ifi.lmu.de/~abel/" target="_blank">http://www2.tcs.ifi.lmu.de/~<u></u>abel/</a><br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</blockquote>
<br>
</blockquote>
<br>
<br>
-- <br>
Andreas Abel  &lt;&gt;&lt;      Du bist der geliebte Mensch.<br>
<br>
Theoretical Computer Science, University of Munich<br>
Oettingenstr. 67, D-80538 Munich, GERMANY<br>
<br>
<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a><br>
<a href="http://www2.tcs.ifi.lmu.de/~abel/" target="_blank">http://www2.tcs.ifi.lmu.de/~<u></u>abel/</a><br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div>