Gentle Haskellers Yes! The layout rule bites again. Ian writes: | Finally, ghci, hi and hugs seem to accept | | > module Foo where | > instance Fractional Int where | > foo = 5 In fact, GHC and Hugs have different interpretations: Hugs treats the 'foo' as part of the 'where', whereas GHC does not. Meanwhile the current draft of the report seems just wrong. The annotated program is: module Foo where {1} <1> instance Fractional Int where {1} <1> foo = 5 So when the algorithm hits the {1} on line 2, no case matches except the catch-all case, so {1} makes it through into the output, which is A Bad Thing. None of these pseudo-lexemes should get through to the output. The "obvious" result is: module Foo where { instance Fractional Int where {} ; foo = 5 } To fix this, it seems to me that all we need do is to add the following second clause to L L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m, (Note 3) = { : } : L ts (m : ms) otherwise This makes sure that the {n} case always has an outcome, and implicitly inserts { } where the layout does not increase. This is an old chestnut, but all the more reason for knocking it on the head (to mix metaphors). Simon
On Mon, Nov 05, 2001 at 05:02:16AM -0800, Simon Peyton-Jones wrote:
To fix this, it seems to me that all we need do is to add the following second clause to L
L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m, (Note 3) = { : } : L ts (m : ms) otherwise
This makes sure that the {n} case always has an outcome, and implicitly inserts { } where the layout does not increase.
The following definition also handles the case "L (t:ts) []" correctly and ensures that {n} and <n> are never passed to parse-error: L (t:ts) [] = L ts [] if t is whitespace = error "lexeme outside of module contents" otherwise L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m = { : } : (L ts (m:ms)) otherwise L (<n>:ts) (m:ms) = ; : (L ts (m:ms)) if m = n = } : (L (<n>:ts) ms) if n < m = L ts (m:ms) otherwise L (t:ts) (m:ms) = } : (L (t:ts) ms) if m /= 0 and parse-error(t) L (}:ts) (0:ms) = } : (L ts ms) L ({:ts) ms = { : (L ts (0:ms)) L (t:ts) ms = t : (L ts ms) L [] [0] = [] L [] (m:ms) = } : L [] ms if m /= 0 Thanks Ian
On Mon, Nov 05, 2001 at 01:52:26PM +0000, Ian Lynagh wrote:
On Mon, Nov 05, 2001 at 05:02:16AM -0800, Simon Peyton-Jones wrote:
L (t:ts) [] = L ts [] if t is whitespace = error "lexeme outside of module contents" otherwise
Actually, changing this to the following means that parse-error doesn't get passed any white space, either: L (t:ts) ms = L ts ms if t is whitespace L (t:ts) [] = error "lexeme outside of module contents" Ian
participants (2)
-
Ian Lynagh -
Simon Peyton-Jones