[GHC] #15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable

#15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.6.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- It should be the case that a code value constructed using typed template haskell should never fail to type check when spliced. Running `ghc Test.hs` with the following two modules produces an error about an ambiguous type variable. https://gist.github.com/5890c14dda73da738d2041c7f677b786 {{{ {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -Wall #-} module Compiler where import Language.Haskell.TH data Operator = Scan | Join Operator Operator deriving Show queryJoin :: Operator queryJoin = Join Scan Scan type QTExp a = Q (TExp a) fix :: (a -> a) -> a fix f = let x = f x in x while :: Monoid m => QTExp (IO m -> IO m) -> QTExp (IO m) while b = [|| fix (\r -> whenM True ($$b r)) ||] whenM :: Monoid m => Bool -> m -> m whenM b act = if b then act else mempty execOp :: Monoid m => Operator -> QTExp (IO m) -> QTExp (IO m) execOp op yld = case op of Scan -> while [|| \r -> ($$(yld) >> r)||] Join left right -> execOp left (execOp right yld) runQuery :: QTExp (IO ()) runQuery = execOp (Join Scan Scan) ([|| return () ||]) }}} {{{ {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -ddump-splices #-} module Test where import qualified Compiler as C main :: IO () main = do $$(C.runQuery) }}} {{{ Test.hs:9:6: error: • Ambiguous type variable ‘a0’ arising from a use of ‘C.whenM’ prevents the constraint ‘(Monoid a0)’ from being solved. Relevant bindings include r_a5GX :: IO a0 (bound at Test.hs:9:6) Probable fix: use a type annotation to specify what ‘a0’ should be. These potential instances exist: instance Monoid a => Monoid (IO a) -- Defined in ‘GHC.Base’ instance Monoid Ordering -- Defined in ‘GHC.Base’ instance Semigroup a => Monoid (Maybe a) -- Defined in ‘GHC.Base’ ...plus 7 others (use -fprint-potential-instances to see them all) • In the expression: (C.whenM True) ((\ r_a5GY -> ((return ()) >> r_a5GY)) r_a5GX) In the first argument of ‘C.fix’, namely ‘(\ r_a5GX -> (C.whenM True) ((\ r_a5GY -> ((return ()) >> r_a5GY)) r_a5GX))’ In the first argument of ‘(>>)’, namely ‘(C.fix (\ r_a5GX -> (C.whenM True) ((\ r_a5GY -> ((return ()) >> r_a5GY)) r_a5GX)))’ | 9 | $$(C.runQuery) | }}} The generated code {{{ Test.hs:9:6-15: Splicing expression C.runQuery ======> C.fix (\ r_a5GV -> (C.whenM True) ((\ r_a5GW -> ((C.fix (\ r_a5GX -> (C.whenM True) ((\ r_a5GY -> ((return GHC.Tuple.()) >> r_a5GY)) r_a5GX))) >> r_a5GW)) r_a5GV)) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15833 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.6.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): If I inline both recursive calls to `execOp` then the code in `Compiler` fails to typecheck. {{{ 26 execOp :: Monoid m => Operator -> QTExp (IO m) -> QTExp (IO m) 27 execOp op yld = 28 case op of 29 Scan -> 30 while [|| \r -> ($$(yld) >> r)||] 31 Join left right -> 32 while [|| \r -> $$(while [|| \r -> ($$(yld) >> r) ||]) >> r ||] }}} {{{ Compiler.hs:32:26: error: • Could not deduce (Monoid a0) arising from a use of ‘while’ from the context: Monoid m bound by the type signature for: execOp :: forall m. Monoid m => Operator -> QTExp (IO m) -> QTExp (IO m) at Compiler.hs:26:1-62 The type variable ‘a0’ is ambiguous These potential instances exist: instance Monoid a => Monoid (IO a) -- Defined in ‘GHC.Base’ instance Monoid Ordering -- Defined in ‘GHC.Base’ instance Semigroup a => Monoid (Maybe a) -- Defined in ‘GHC.Base’ ...plus 7 others (use -fprint-potential-instances to see them all) • In the expression: while [|| \ r -> ($$(yld) >> r) ||] In the Template Haskell splice $$(while [|| \ r -> ($$(yld) >> r) ||]) In the first argument of ‘(>>)’, namely ‘$$(while [|| \ r -> ($$(yld) >> r) ||])’ | 32 | while [|| \r -> $$(while [|| \r -> ($$(yld) >> r) ||]) >> r ||] | }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15833#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.6.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): Here is a minimised version which still exhibits the same failure. {{{ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wall #-} module Compiler where import Language.Haskell.TH type QTExp a = Q (TExp a) fix :: (a -> a) -> a fix f = let x = f x in x while :: Monoid m => QTExp (IO m -> IO m) -> QTExp (IO m) while b = [|| fix (\r -> whenM ($$b r)) ||] whenM :: Monoid m => a -> m whenM _ = mempty execOp :: forall m . Monoid m => QTExp (IO m) execOp = while [|| \r -> $$(while @m [|| id ||]) >> r ||] runQuery :: QTExp (IO ()) runQuery = execOp }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15833#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.6.1 Resolution: | Keywords: | TypedTemplateHaskell Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by mpickering): * keywords: => TypedTemplateHaskell -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15833#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Template Haskell | Version: 8.6.1 Resolution: | Keywords: | TypedTemplateHaskell Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by goldfire): * component: Compiler => Template Haskell -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15833#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15833: Typed template haskell quote fails to typecheck when spliced due to an ambiguous type variable -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Template Haskell | Version: 8.6.1 Resolution: | Keywords: | TypedTemplateHaskell Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): My office mate ran into exactly this bug when trying to stage a non- trivial (500 line) program. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15833#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC