Skip to content

TH Clauses do not play well with splicing and TH quotes

template-haskell features a Clause type. This represents a clause in a defintion. Eg:

[d|
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
|]

desguars to

[FunD fib_0 
  [Clause [LitP (IntegerL 0)] (NormalB (LitE (IntegerL 1))) []
  ,Clause [LitP (IntegerL 1)] (NormalB (LitE (IntegerL 1))) []
  ,Clause [VarP n_1] 
    (NormalB (InfixE (Just (AppE (VarE fib_0) (InfixE (Just (VarE n_1)) (VarE GHC.Num.-) (Just (LitE (IntegerL 1)))))) (VarE GHC.Num.+) (Just (AppE (VarE fib_0) (InfixE (Just (VarE n_1)) (VarE GHC.Num.-) (Just (LitE (IntegerL 2)))))))) 
    []
  ]
]

A Clause consists of the patterns on the LHS, the body, and any where clauses.

It's quite natural to build up a larger function based on Clauses, eg, yesod-core's route code does this quite extensively. Yet, given a set of Clauses, we don't have a way to splice this into a TH quote, eg, we can't do something like:

fib_clauses :: [Clause]
fib_clauses = ...
fib = $(fib_clauses)

We also don't have a way to construct a Clause using TH quotes.

This poses an issue for migrating users towards TH quotes and splices rather than manually constructing ASTs.

See also: #24009

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