I could not figure out why I am getting "GHC stage restriction" in the following code:
import Language.Haskell.TH
rules :: [ExpQ]
rules = [ [| \a -> a |], [| \_ -> 1 |] ]
findTransforms :: Int -> [ExpQ] -> Bool
findTransforms _ [] = False
findTransforms e (r:rs) = if ($r e) == 1 then True else findTransforms e rs
(Do not worry if code does not make anything useful - it is extracted minimal example obfuscated for clarity).
I do not call any functions from spliced code. Why stage restriction?
EDIT1: edited to give even simpler code example
This fails for the same reason you can't write
eval :: ExpQ -> Int
eval expr = $expr
because it would require compilation at run-time.
One solution is to make findTransforms
compile-time as well by returning an expression of nested if
expressions rather than the value of said expression.
findTransforms :: Int -> [ExpQ] -> ExpQ
findTransforms _ [] = [| False |]
findTransforms e (r:rs) = [| if $r e == 1 then True else $(findTransforms e rs) |]
Of course, this means that you'll have to splice it when you want to use it.