Skip to content

Code is levity-polymorphic, but CodeQ and TExpQ aren't

On HEAD, the following will typecheck:

{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TemplateHaskell #-}
module Bug where

import GHC.Exts (Int#)
import Language.Haskell.TH

a :: Code Q Int#
a = [|| 42# ||]

But @buggymcbugfix observed that neither of the following will typecheck:

b :: CodeQ Int#
b = a

c :: TExpQ Int#
c = examineCode a
[1 of 1] Compiling Bug              ( Bug.hs, interpreted )

Bug.hs:11:12: error:
    • Expecting a lifted type, but ‘Int#’ is unlifted
    • In the first argument of ‘CodeQ’, namely ‘Int#’
      In the type signature: b :: CodeQ Int#
   |
11 | b :: CodeQ Int#
   |            ^^^^

Bug.hs:14:12: error:
    • Expecting a lifted type, but ‘Int#’ is unlifted
    • In the first argument of ‘TExpQ’, namely ‘Int#’
      In the type signature: c :: TExpQ Int#
   |
14 | c :: TExpQ Int#
   |            ^^^^

This is because Code is levity polymorphic in its last argument, but neither CodeQ nor TExpQ are. It feels like they should be for the sake of consistency.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information