haskell-suite / haskell-src-exts

Manipulating Haskell source: abstract syntax, lexer, parser, and pretty-printer
Other
193 stars 95 forks source link

Bad requirement of MultiParamTypeClasses #304

Open cblp opened 8 years ago

cblp commented 8 years ago
{-# LANGUAGE FlexibleContexts #-}

module Test where

import Control.Monad.Reader

test :: MonadReader a m => m a
test = undefined

This code is OK for GHC, but haskell-src-exts fails with "MultiParamTypeClasses language extension is not enabled".

pjonsson commented 8 years ago

Can you briefly explain why MonadReader isn't a MultiParamTypeClass or why parsing that shouldn't require MultiParamTypeClasses?

cblp commented 8 years ago

This code doesn't define multi-parameter type classes, so it doesn't need this extension.

mpickering commented 8 years ago

I investigated this a bit and it seems that FlexibleContexts is not a very well specified extension. Because of this it seems that the best specification is the implementation and so the program should be accepted.

On 31 Jul 2016 3:06 p.m., "Yuriy Syrovetskiy" notifications@github.com wrote:

This code doesn't define multi-parameter type classes, so it doesn't need this extension.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/haskell-suite/haskell-src-exts/issues/304#issuecomment-236431889, or mute the thread https://github.com/notifications/unsubscribe-auth/ABKQkU-BIJkPaHfdusEPaP98fm-cIgnfks5qbKvegaJpZM4IO480 .

cblp commented 8 years ago

This code doesn't use the fact MonadReader is a class, it just uses that as a symbol in a non-trivial context expression, so FlexibleContexts is in play.

pjonsson commented 8 years ago

I tried to think of other extensions that have a syntactic footprint that allow you to use the syntax without enabling the extension but I couldn't come up with any. Our lexer carries enough state to refuse to lex certain tokens in some positions unless an extension is enabled. In this particular case I imagine the type checker would in general choke when trying to type check the function unless MPTCs are enabled.

I don't think GHC's intention is to enable MPTC since they carefully avoid stating anything about requiring that; all they state is that they lift the restriction of a class applied to type variable(s). Quoting the relevant parts of the GHC documentation for FlexibleContexts:

In Haskell 98 the context of a class declaration (which introduces superclasses) must be simple; that is, each predicate must consist of a class applied to type variables. The flag -XFlexibleContexts (Section 7.13.2, “The context of a type signature”) lifts this restriction, so that the only restriction on the context in a class declaration is that the class hierarchy must be acyclic.

I'm not sure where they get the phrasing "applied to type variables" from because Haskell 98 defines the grammar for type classes as:

topdecl ::= class [scontext =>] tycls tyvar [where cdecls]
scontext ::= simpleclass
                | ( simpleclass1 , ... , simpleclassn ) (n>=0)
simpleclass ::= qtycls tyvar

There is only one type variable in simpleclass so while you might have a context with multiple type classes each one of them is only applied to a single type variable.

Verifying that the class hierarchy is acyclic is not a job for the parser so we can ignore that part for this discussion.

mpickering commented 8 years ago

I think we should accept it anyway as there is no sense differing from what GHC accepts. The two should match whether that means fixing HSE or GHC. A recent relevant ticket is https://ghc.haskell.org/trac/ghc/ticket/12121

Comment 2 implies that this program should be accepted if I am reading it correctly.

pjonsson commented 8 years ago

Roman has in the past reported bugs against GHC and gotten them fixed so it's not set in stone that HSE has to follow GHC. Simon admits that the context treatment in GHC doesn't follow the standard in the sibling-ticket (https://ghc.haskell.org/trac/ghc/ticket/12120).

My guess about the behaviour for extensions "leaking in" is answered by Simon in comment 6 in this ticket: https://ghc.haskell.org/trac/ghc/ticket/8883. The fact that the function there requires FlexibleContexts for type checking means the compiler should reject the function under Haskell 2010 even if the function would type check with FlexibleContexts enabled.

infinity0 commented 4 years ago

Why was this bug closed? It is still affecting stylish-haskell, which now differs from GHC's behaviour.

Moreovere, hlint complains about "unused language pragma" but remove it makes stylish-haskell fail.