Template Haskell's TupleT considers unary tuples as a valid types.
I don't know how tuples are internally implemented in GHC, but the Haskell report (3.8) specifically establishes two as their lower size bound.
When provided a zero (or null list) arguments, all TupleT, TupP and TupE behave like the unit type (which is certainly reasonable). However, they handle argument 1 (or the singleton list) in different ways:
TupleP [pat]is equivalent to
pat(which again, is perfectly reasonable)
TupE [exp]behaves as exp (again, it seems right)
VarT ''Intis a different type than
See the following two examples:
tupE [exp]behaves as expected:
Prelude Language.Haskell.TH> $(sigE (tupE [[|1|]]) (conT ''Int)) 1
Prelude Language.Haskell.TH> $(sigE [|1|] (tupleT 1 `appT` conT ''Int)) <interactive>:1:2: No instance for (Num (Int)) arising from the literal `1' at <interactive>:1:2-40 Possible fix: add an instance declaration for (Num (Int)) In the expression: $(sigE [| 1 |] (tupleT 1 `appT` conT 'Int)) In the definition of `it': it = $(sigE [| 1 |] (tupleT 1 `appT` conT 'Int))
Probably, since unary tuples are not legal, the typechecker should simply raise an error when
TupleT is found to have received
1 as argument.