Skip to content

`unboxedTupleTypeName 2` does not return the same Name as ''(#,#)

I recently uncovered an unfortunate property of template-haskell unboxedTupleTypeName function. For context, template-haskell offers a family of functions for retrieving tuple-related Names:

tupleTypeName :: Int -> Name
tupleDataName :: Int -> Name
unboxedTupleTypeName :: Int -> Name
unboxedTupleDataName :: Int -> Name

For each of these functions f, I would expect that calling f <N> would return the same Name as manually quoting an N-ary tuple. This property holds true for tupleDataName (as of GHC 9.10.1-rc1):

{-# LANGUAGE TemplateHaskellQuotes #-}
module Main (main) where

import Language.Haskell.TH

test :: Name -> Name -> IO ()
test n1 n2 = do
  putStrLn $ "LHS name:  " ++ show n1
  putStrLn $ "RHS name:  " ++ show n2
  putStrLn $ "Same name: " ++ show (n1 == n2)

main :: IO ()
main = do
  test (tupleTypeName 2) ''(,)
  test (tupleDataName 2)  '(,)
$ runghc-9.10.0.20240426 Foo.hs
LHS name:  GHC.Tuple.Tuple2
RHS name:  GHC.Tuple.Tuple2
Same name: True
LHS name:  GHC.Tuple.(,)
RHS name:  GHC.Tuple.(,)
Same name: True

However, this property does not hold true for unboxedTupleTypeName and unboxedTupleDataName:

{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE UnboxedTuples #-}
module Main (main) where

import Language.Haskell.TH

test :: Name -> Name -> IO ()
test n1 n2 = do
  putStrLn $ "LHS name:  " ++ show n1
  putStrLn $ "RHS name:  " ++ show n2
  putStrLn $ "Same name: " ++ show (n1 == n2)

main :: IO ()
main = do
  test (unboxedTupleTypeName 2) ''(#,#)
  test (unboxedTupleDataName 2)  '(#,#)
$ runghc-9.10.0.20240426 Foo.hs
LHS name:  GHC.Prim.Tuple2#
RHS name:  GHC.Types.Tuple2#
Same name: False
LHS name:  GHC.Prim.(#,#)
RHS name:  GHC.Types.(#,#)
Same name: False

Here, we see that unboxedTupleTypeName 2 returns GHC.Prim.Tuple2# which, as far as I can tell, is not a Name that actually exists. Similarly for unboxedTupleDataName 2. Is there a reason why these shouldn't return the same Names as ''(#,#) and '(#,#)?

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