Keith S. Wansbrough wrote:
> 
> > Using Hugs1.3c with p1, the system crashes typechecking the
> > following program.
> [..]
> 
> > >type FN = Fix N
> 
> [..]
> 
> > >instance (HasParser x) => HasParser (N x) where
> > > parser = [Num 3]
> > >
> > >instance HasParser (f (Fix f)) => HasParser (Fix f) where
> > > parser = map In parser
> 
> [..]
> 
> > >parserFN::Parser FN
> > >parserFN = parser
> 
> And so it should.  Let's see what happens:
> 
> 1. parserFN typechecks if there's an instance (HasParser FN); this is
> a type synonym so we're really looking for (HasParser (Fix N)).
> 
> 2. This matches the second rule; so we are now looking for the context
> to that rule, namely (HasParser (N (Fix N))).
> 
> 3. *This* in turn matches the first rule, and so we are now looking
> for its context, namely (HasParser (Fix N)).
> 
> 4. Repeat from step 2 until the system crashes.
> 
> I don't see why you need the context in the first rule... you never
> use (HasParser x) in the definition of parser.  If you delete this
> context, then the example should work fine.
> 
The example is simplified, but I need it. 

I am using "ParseLib" and the instance declaration could be:

>instance (HasParser x) => HasParser (N x) where
> parser = pNum
>      +++ pAdd
> where pNum = do { n <- integer ; return (Num n) } 
>       pAdd = do { symbol "("; 
>                   x <- parser; symbol "+"; y <- parser; 
>                   symbol ")";
>                   return (Add x y) 
>                }

You justify the error but I think that the Hugs interpreter should 
not crash. IMO, It would be better that the system could detect the 
circular declarations and report the error to the programmer. 

By the way, P. Azero has suggested to add:

> parserFN :: HasParser (Fix N) => Parser FN

Now, the program type checks but Hugs crashes when I call:

? parserFN


Greetings, Jose Labra

PS. I have been able to bypass the problem adding a new class:

>class HasParserF f where
> parserF::Parser x -> Parser (f x)
>
>instance (HasParser x) => HasParser (N x) where 
> parser = parserN parser
>
>instance HasParserF N where parserF parser = ...
>
>instance (HasParserF f) => HasParser (Fix f) where
> parser = map In (parserF parser)
>
>parserFN::Parser (Fix N)
>parserFN = parser

But it looks a little ugly :(

Reply via email to