With pattern guards, it's difficult to say whether it is never 'useful' to have things like the following work:
C x | C' y z <- f x = ... But I'd also shy away from changing the behavior because it causes a lot of consistency issues. In let f <vs1> | gs1 = es1 h <vs2> | gs2 = es2 ... 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? 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? Also, it might have some weird consequences for moving code around. Like: let Just x | x > 0 = Just 1 let Just x | y > 0 = Just 1 y = x let Just x | b = Just 1 where b = x > 0 let Just x | b = Just 1 b = x > 0 These all behave the same way now. Which ones should change? If Haskell had a non-recursive let, that'd probably be a different story. But it doesn't. On Tue, Jul 9, 2013 at 1:12 PM, Andreas Abel <andreas.a...@ifi.lmu.de>wrote: > Thanks, Dan and Roman, for the explanation. So I have to delete the > explanation "non-recursive let = single-branch case" from my brain. > > I thought the guards in a let are assertations, but in fact it is more > like an if. Ok. > > But then I do not see why the pattern variables are in scope in the guards > in > > let p | g = e > > 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. > > 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. > > Cheers, > Andreas > > On 09.07.2013 17:05, Dan Doel wrote:> The definition > > > > > Just x | x > 0 = Just 1 > > > > is recursive. It conditionally defines Just x as Just 1 when x > 0 (and > > as bottom otherwise). So it must know the result before it can test the > > guard, but it cannot know the result until the guard is tested. Consider > > an augmented definition: > > > > Just x | x > 0 = Just 1 > > | x <= 0 = Just 0 > > > > What is x? > > On 09.07.2013 17:49, Roman Cheplyaka wrote: > >> As Dan said, this behaviour is correct. >> >> The confusing thing here is that in case expressions guards are attached >> to the patterns (i.e. to the lhs), while in let expressions they are >> attached to the rhs. >> >> So, despite the common "Just x | x > 0" part, your examples mean rather >> different things. >> >> Here's the translation of 'loops' according to the Report: >> >> loops = >> let Just x = >> case () of >> () | x > 0 -> Just 1 >> in x >> >> Here it's obvious that 'x' is used in the rhs of its own definition. >> >> Roman >> >> * Andreas Abel <andreas.a...@ifi.lmu.de> [2013-07-09 16:42:00+0200] >> >>> Hi, is this a known bug or feature of GHC (7.4.1, 7.6.3)?: >>> >>> I got a looping behavior in one of my programs and could not explain >>> why. When I rewrote an irrefutable let with guards to use a case >>> instead, the loop disappeared. Cut-down: >>> >>> works = case Just 1 of { Just x | x > 0 -> x } >>> >>> loops = let Just x | x > 0 = Just 1 in x >>> >>> works returns 1, loops loops. If x is unused on the rhs, the >>> non-termination disappears. >>> >>> works' = let Just x | x > 0 = Just 1 in 42 >>> >>> Is this intended by the Haskell semantics or is this a bug? I would >>> have assumed that non-recursive let and single-branch case are >>> interchangeable, but apparently, not... >>> >>> Cheers, >>> Andreas >>> >>> -- >>> Andreas Abel <>< Du bist der geliebte Mensch. >>> >>> Theoretical Computer Science, University of Munich >>> Oettingenstr. 67, D-80538 Munich, GERMANY >>> >>> andreas.a...@ifi.lmu.de >>> http://www2.tcs.ifi.lmu.de/~**abel/ <http://www2.tcs.ifi.lmu.de/~abel/> >>> >>> ______________________________**_________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/**mailman/listinfo/haskell-cafe<http://www.haskell.org/mailman/listinfo/haskell-cafe> >>> >> >> > > -- > Andreas Abel <>< Du bist der geliebte Mensch. > > Theoretical Computer Science, University of Munich > Oettingenstr. 67, D-80538 Munich, GERMANY > > andreas.a...@ifi.lmu.de > http://www2.tcs.ifi.lmu.de/~**abel/ <http://www2.tcs.ifi.lmu.de/~abel/> > > ______________________________**_________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/**mailman/listinfo/haskell-cafe<http://www.haskell.org/mailman/listinfo/haskell-cafe> >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe