[GHC] #12936: Type inference regression in GHC HEAD
GHC
ghc-devs at haskell.org
Wed Dec 7 02:03:33 UTC 2016
#12936: Type inference regression in GHC HEAD
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner:
Type: bug | Status: new
Priority: high | Milestone: 8.2.1
Component: Compiler | Version: 8.1
(Type checker) |
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: GHC rejects
Unknown/Multiple | valid program
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
First noticed in https://ghc.haskell.org/trac/ghc/ticket/12790#comment:8.
This causes `parsec-3.1.11` to fail to build with GHC HEAD.
Here is as small of a test case that I can manage, with no dependencies:
{{{#!hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Parsec (makeTokenParser) where
import Data.Char (digitToInt)
data ParsecT s u (m :: * -> *) a
instance Functor (ParsecT s u m) where
fmap = undefined
instance Applicative (ParsecT s u m) where
pure = undefined
(<*>) = undefined
instance Monad (ParsecT s u m) where
return = undefined
(>>=) = undefined
fail = undefined
parserZero :: ParsecT s u m a
parserZero = undefined
infixr 1 <|>
(<|>) :: (ParsecT s u m a) -> (ParsecT s u m a) -> (ParsecT s u m a)
(<|>) = undefined
class (Monad m) => Stream s m t | s -> t where
digit :: (Stream s m Char) => ParsecT s u m Char
digit = undefined
hexDigit :: (Stream s m Char) => ParsecT s u m Char
hexDigit = undefined
octDigit :: (Stream s m Char) => ParsecT s u m Char
octDigit = undefined
option :: (Stream s m t) => a -> ParsecT s u m a -> ParsecT s u m a
option = undefined
many1 :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m [a]
many1 = undefined
data GenTokenParser s u m
= TokenParser {
float :: ParsecT s u m Double,
naturalOrFloat :: ParsecT s u m (Either Integer Double)
}
makeTokenParser :: (Stream s m Char) => GenTokenParser s u m
makeTokenParser
= TokenParser{
float = float_
, naturalOrFloat = naturalOrFloat_
}
where
-----------------------------------------------------------
-- Numbers
-----------------------------------------------------------
naturalOrFloat_ = lexeme natFloat
float_ = lexeme floating
-- floats
floating = do{ n <- decimal
; fractExponent n
}
natFloat = zeroNumFloat
<|> decimalFloat
zeroNumFloat = do{ n <- hexadecimal <|> octal
; return (Left n)
}
<|> decimalFloat
decimalFloat = do{ n <- decimal
; option (Left n)
(fractFloat n)
}
fractFloat n = do{ f <- fractExponent n
; return (Right f)
}
fractExponent n = do{ fract <- fraction
; expo <- option "" exponent'
; readDouble (show n ++ fract ++ expo)
}
<|>
do{ expo <- exponent'
; readDouble (show n ++ expo)
}
where
readDouble s =
case reads s of
[(x, "")] -> return x
_ -> parserZero
fraction = do{ digits <- many1 digit
; return ('.' : digits)
}
exponent' = do{ e <- decimal
; return (show e)
}
-- integers and naturals
decimal = number 10 digit
hexadecimal = number 16 hexDigit
octal = number 8 octDigit
number base baseDigit
= do{ digits <- many1 baseDigit
; let n = foldl (\x d -> base*x + toInteger (digitToInt d)) 0
digits
; seq n (return n)
}
-----------------------------------------------------------
-- White space & symbols
-----------------------------------------------------------
lexeme p = do{ x <- p; whiteSpace; return x }
whiteSpace = return ()
}}}
In GHC 8.0.1 and 8.0.2, this compiles without issue. But on GHC HEAD:
{{{
$ ~/Software/ghc/inplace/bin/ghc-stage2 Parsec.hs
[1 of 1] Compiling Parsec ( Parsec.hs, Parsec.o )
Parsec.hs:83:27: error:
• Could not deduce (Stream s m t0) arising from a use of ‘option’
from the context: Stream s m Char
bound by the type signature for:
makeTokenParser :: Stream s m Char => GenTokenParser s
u m
at Parsec.hs:53:1-60
The type variable ‘t0’ is ambiguous
Relevant bindings include
decimalFloat :: ParsecT s u1 m (Either Integer Double)
(bound at Parsec.hs:82:5)
fractFloat :: forall b a1 u a2.
(Read b, Show a2) =>
a2 -> ParsecT s u m (Either a1 b)
(bound at Parsec.hs:87:5)
fractExponent :: forall a1 u a2.
(Show a2, Read a1) =>
a2 -> ParsecT s u m a1
(bound at Parsec.hs:91:5)
fraction :: forall u. ParsecT s u m [Char]
(bound at Parsec.hs:105:5)
exponent' :: forall u. ParsecT s u m String
(bound at Parsec.hs:109:5)
decimal :: forall u. ParsecT s u m Integer
(bound at Parsec.hs:114:5)
lexeme :: forall b. ParsecT s u m b -> ParsecT s u m b
(bound at Parsec.hs:127:5)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-
relevant-binds)
• In a stmt of a 'do' block: option (Left n) (fractFloat n)
In the expression:
do { n <- decimal;
option (Left n) (fractFloat n) }
In an equation for ‘decimalFloat’:
decimalFloat
= do { n <- decimal;
option (Left n) (fractFloat n) }
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12936>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list