Is it possible to transform a recursive TH function into an equivalent form which will compile? The following definition doesn't work, because in order to compile fact you must first compile fact.
fact :: ExpQ -> ExpQ
fact n = [|
case $n of
1 -> 1
_ -> $n * $(fact [| $n - 1 |]) |]
This simple example is easily solved (fact n = [| product [ 1.. $n] |]) but in the general case, if it is not possible to rewrite a given function as a loop, can a recursive TH function be defined? Is there even a single example for which this doable?
To clarify for future readers: this question is specifically about writing recursive TH functions - not about 'how do I splice the factorial function'.
The answer to my question turned out to be remarkably simple:
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad.Fix (fix)
import Language.Haskell.TH
fact = [| \f x -> $([|
case x of
1 -> 1
_ -> f $([| x - 1 |]) * x |]) |]
factorial = [| fix $fact |]
fact can be compiled because it is no longer recursive, and [| fix $fact |] is compiled at a later time, so no more infinite recursive definitions.
This version of fact looks slightly different than the original, but you can write the new fact exactly as the old one and transform it later:
fact' recurse n = [|
case $n of
1 -> 1
_ -> $n * $(recurse [| $n - 1 |]) |]
fact = [| \x -> $((\f -> [| \x -> $(fact (\x -> [| $f $x |]) [| x |]) |]) [| x |]) |]