Skip to content

Reified function types use AppT (rather than AppKindT) to apply matchabilities to (->)

If you run this program:

{-# LANGUAGE TemplateHaskell #-}
module Main where

import Language.Haskell.TH

main :: IO ()
main = do
  putStrLn $(reify 'id >>= stringE . pprint)
  putStrLn $(reify 'id >>= stringE . show)

It will output this:

GHC.Base.id :: forall (a_0 :: *) .
               (->) 'GHC.Types.Unmatchable a_0 a_0
VarI GHC.Base.id (ForallT [KindedTV a_6989586621679019003 SpecifiedSpec StarT] [] (AppT (AppT (AppT ArrowT (PromotedT GHC.Types.Unmatchable)) (VarT a_6989586621679019003)) (VarT a_6989586621679019003))) Nothing

The type of id that is reported, (->) 'Unmatchable a_0 a_0, is rather strange, as it treats Unmatchable as if it were a visible argument to (->). The last line reveals the likely culprit behind this oddity: the AST uses AppT ArrowT (PromotedT GHC.Types.Unmatchable) rather than AppKindT ArrowT (PromotedT GHC.Types.Unmatchable), which is what I would have expected.