[Haskell-cafe] GHC bug? Let with guards loops
Andreas Abel
andreas.abel at ifi.lmu.de
Tue Jul 9 19:12:29 CEST 2013
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.abel at 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.abel at ifi.lmu.de
>> http://www2.tcs.ifi.lmu.de/~abel/
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> 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.abel at ifi.lmu.de
http://www2.tcs.ifi.lmu.de/~abel/
More information about the Haskell-Cafe
mailing list