[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