Typed splices and type checking
J. Garrett Morris
Garrett.Morris at ed.ac.uk
Fri Mar 27 14:30:10 UTC 2015
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.
More information about the Glasgow-haskell-users
mailing list