<div dir="ltr"><div><div><div><div><div><div><div><div>With pattern guards, it's difficult to say whether it is never 'useful' to have things like the following work:<br><br></div> C x | C' y z <- f x = ...<br>
<br></div>But I'd also shy away from changing the behavior because it causes a lot of consistency issues. In<br><br></div> let<br></div> f <vs1> | gs1 = es1<br></div> h <vs2> | 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'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'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 <vs>? 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 > 0 = Just 1<br><br></div><div> let Just x | y > 0 = Just 1<br></div><div> y = x<br><br></div><div> let Just x | b = Just 1<br></div><div> where b = x > 0<br>
<br></div><div> let Just x | b = Just 1<br></div><div> b = x > 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'd probably be a different story. But it doesn'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"><<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a>></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 "non-recursive let = single-branch case" 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:> The definition<div class="im HOEnZb"><br>
><br>
> Just x | x > 0 = Just 1<br>
><br></div><div class="im HOEnZb">
> is recursive. It conditionally defines Just x as Just 1 when x > 0 (and<br>
> as bottom otherwise). So it must know the result before it can test the<br>
> guard, but it cannot know the result until the guard is tested. Consider<br>
> an augmented definition:<br>
><br></div><div class="im HOEnZb">
> Just x | x > 0 = Just 1<br></div><div class="im HOEnZb">
> | x <= 0 = Just 0<br>
><br>
> 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 "Just x | x > 0" part, your examples mean rather<br>
different things.<br>
<br>
Here's the translation of 'loops' according to the Report:<br>
<br>
loops =<br>
let Just x =<br>
case () of<br>
() | x > 0 -> Just 1<br>
in x<br>
<br>
Here it's obvious that 'x' is used in the rhs of its own definition.<br>
<br>
Roman<br>
<br>
* Andreas Abel <<a href="mailto:andreas.abel@ifi.lmu.de" target="_blank">andreas.abel@ifi.lmu.de</a>> [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 > 0 -> x }<br>
<br>
loops = let Just x | x > 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' = let Just x | x > 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 <>< 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 <>< 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>