Strangeness in the syntax of types

Niklas Broberg niklas.broberg at gmail.com
Thu Jun 18 17:18:48 EDT 2009


Hi all,

I've had a curious bug report [1] for haskell-src-exts, pointing to a
difference in behavior between haskell-src-exts and GHC. Digging
further, it seems to me like GHC is behaving quite strange in this
instance, but since we don't have formal documentation for the
extensions I can't be sure. I'm *almost* convinced this is a bug in
GHC, but with these type extensions I can never be quite sure. Thus
I'm putting it out here in the hope that someone will either explain
why it is this way, or tell me to go file a bug report.

The gist of it is the following piece of code:

> multipleCtx :: Eq a => Show a => a
> multipleCtx = undefined

GHC accepts this code, while haskell-src-exts requires parentheses
around the latter part of the signature, i.e. Eq a => (Show a => a).
The difference is the following productions

haskell-src-exts:
> ctype :: { PType }
>       : 'forall' ktyvars '.' ctype
>       | context '=>' type
>       | type

GHC:
> ctypedoc  :: { LHsType RdrName }
>        : 'forall' tv_bndrs '.' ctypedoc
>        | context '=>' ctypedoc
>        | gentypedoc

Notice GHC's recursive call to ctypedoc after the =>. I have no idea
what the doc suffix on the production is intended to indicate though -
and I was curious to find a separate set of rules that don't have that
suffix:

> ctype	:: { LHsType RdrName }
> 	: 'forall' tv_bndrs '.' ctype
>	| context '=>' type
>	| type

This one looks just like the one that haskell-src-exts uses - type
instead of ctype after the =>. So what's the difference between the
two in GHC? Looking further, the former is used in top-level type
signatures, while the latter is used for pretty much everything else.
In particular, you can't put a ctypedoc inside parentheses, there you
would have to use ctype. So while GHC accepts the above definition, it
rejects e.g. the (seemingly) equivalent

> multipleCtx :: (Eq a => Show a => a)
> multipleCtx = undefined

My guess would be that there's a bug here, and that it's the recursive
call to ctypedoc that is at fault, it should really be gentypedoc. On
the other hand there's no problem parsing either, so there's no
technical reason not to allow chained contexts without parentheses,
even though I personally think it looks quite awkward.

Enough rambling - can someone make me the wiser?

Cheers,

/Niklas

[1] http://trac.haskell.org/haskell-src-exts/ticket/37


More information about the Glasgow-haskell-users mailing list