Open lichtemo opened 10 years ago
Can you provide a reproducible test case? Here's what I observe:
Prelude Language.Haskell.Exts> let ParseOk ast = parseExp "1 Prelude.* 2"
Prelude Language.Haskell.Exts> ast
InfixApp (Lit (Int 1)) (QVarOp (Qual (ModuleName "Prelude") (Symbol "*"))) (Lit (Int 2))
Prelude Language.Haskell.Exts> prettyPrint ast
"1 Prelude.* 2"
When I use TypeOperators s :: Int P.-> Bool is pretty printed to s :: Int P .-> Bool
But the problem only occurs with the -> operator. I am actually nut sure, whether -> is a valid type operator but the example is from at least two Haskell files from hackage.
Oh, so this is about type operators.
This happens because it parses the dot as a part of the .->
operator.
Prelude Language.Haskell.Exts> parseTypeWithMode defaultParseMode { extensions = [EnableExtension TypeOperators] } "Int P.-> Bool"
ParseOk (TyInfix (TyApp (TyCon (UnQual (Ident "Int"))) (TyCon (UnQual (Ident "P")))) (UnQual (Symbol ".->")) (TyCon (UnQual (Ident "Bool"))))
That in turn happens because ->
is syntax, not an operator.
HSE does correctly parse old-style qualified type ops (ones that begin with a colon):
Prelude Language.Haskell.Exts> parseTypeWithMode defaultParseMode { extensions = [EnableExtension TypeOperators ] } "Int P.:> Bool"
ParseOk (TyInfix (TyCon (UnQual (Ident "Int"))) (Qual (ModuleName "P") (Symbol ":>")) (TyCon (UnQual (Ident "Bool"))))
It doesn't know about new-style type operator constructors (that can contain any symbols):
Prelude Language.Haskell.Exts> parseTypeWithMode defaultParseMode { extensions = [EnableExtension TypeOperators ] } "Int P.> Bool"
ParseFailed (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 5}) "Parse error: P.>"
There is one more not supported TypeOperators feature - type operator export. Combined into one test file:
{-# LANGUAGE TypeOperators #-}
module TypeOperatorDataConstructor
((+)(..), type (+)) -- not supported
where
data a + b = L a | R b
either1 :: (t1 -> t) -> (t2 -> t) -> (t1 + t2) -> t -- pass
either2 :: (t1 -> t) -> (t2 -> t) -> (t1 E.+ t2) -> t -- not supported
There's a reasonably complete test case from @bpfoley at https://github.com/ndmitchell/hlint/issues/400:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
module N where
type (++) a b = (a,b)
-- Correctly parses OK in GHCi & hlint
f1 :: Eq (Bool ++ Bool) => a
f1 = undefined
-- Correctly parses OK in GHCi & hlint
f2 :: Eq ((N.++) Bool Bool) => a
f2 = undefined
-- Parses OK in GHCi, but incorrectly a parse error in hlint
f3 :: Eq (Bool N.++ Bool) => a
f3 = undefined
-- Parse error in GHCi (because it's a prefix op), but incorrectly
-- parses OK in hlint
f4 :: Eq (Bool (N.++) Bool) => a
f4 = undefined
pp-haskell pretty prints for example Prelude.* to Prelude[space].* which is not correct anymore