Skip to content

Template Haskell boxes singleton unboxed tuples when splicing them

As noticed here, this program somehow compiles:

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

import Language.Haskell.TH.Lib
import Language.Haskell.TH.Ppr
import Language.Haskell.TH.Syntax

f :: $([t| (# Int #) |]) -> Int
f x = x

g :: $(unboxedTupleT 1 `appT` conT ''Int) -> Int
g x = x

Despite the fact that (# Int #) and Int are most definitely //not// the same type! If you compile with -ddump-splices, you'll see what's going on:

$ /opt/ghc/head/bin/ghc Bug.hs -ddump-splices
[1 of 1] Compiling Bug              ( Bug.hs, Bug.o )
Bug.hs:12:8-40: Splicing type
    unboxedTupleT 1 `appT` conT ''Int ======> Int
Bug.hs:9:8-23: Splicing type [t| (# Int #) |] ======> Int

It appears that the splicing machinery is turning (# Int #) into Int behind the scenes. Luckily, this should be easy to fix. Patch coming soon.

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