
Hello, I've run into another misunderstanding with Template Haskell and typed splices. For example, I was hoping to use typed splices to generate earlier errors from Printf. Here's the world's least handy printf:
class Printf t where printf :: String -> Q (TExp String) -> Q (TExp t)
instance Printf String where printf s t | '%' `notElem` s = [|| $$t ++ s ||] | otherwise = fail ("Unexpected format %" ++ [c]) where (_, _:c:_) = break ('%' ==) s
instance Printf t => Printf (Char -> t) where printf s t | c /= 'c' = fail ("Unexpected format %" ++ [c] ++ " for character") | otherwise = [|| \c -> $$(printf s'' [|| $$t ++ s' ++ [c] ||]) ||] where (s', '%':c:s'') = break ('%' ==) s
Now, consider these two definitions:
f :: Char -> String f = $$(printf "foo %c" [||""||])
h :: Char -> String h y = $$(printf "foo %c" [||""||]) y
I would have expected these to be equivalent, from a type checking perspective. However, while the first types fine, the second generates the error message:
Printing.hs:14:12: No instance for (Printf t0) arising from a use of `printf' The type variable `t0' is ambiguous Note: there are several potential instances: instance Printf t => Printf (Char -> t) -- Defined at Printf.hs:20:10 instance Printf String -- Defined at Printf.hs:9:10 In the expression: printf "foo %c" [|| "" ||] In the Template Haskell splice $$(printf "foo %c" [|| "" ||]) In the expression: $$(printf "foo %c" [|| "" ||])
Should I have anticipated this? Ought the interaction of typed splices and eta-expansion be problematic? /g -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.