RE: [Template-haskell] RE: Template Haskell...
Our plan for error messages was failWith :: String -> Q () Would that do? In this way you can format your own error message. So if you had f :: Int -> Q Exp f 0 = failWith "Postitive n required f n = [| \x -> x+n |] then the splice ....$(f 0)..... would elicit the error message Foo.hs:8: Error in splice $(f 0): Positive n required Is that what you want? Simon | -----Original Message----- | From: Alastair Reid [mailto:alastair@reid-consulting-uk.ltd.uk] | Sent: 29 October 2003 21:47 | To: Simon Peyton-Jones; template-haskell@haskell.org | Subject: Re: [Template-haskell] RE: Template Haskell... | | More things for the TH wish-list: | | I've been using TH to create language extensions. | Unfortunately, the error messages are horrible because: | | 1) They contain a header generated by TH. | This contains useful information like line numbers but it | talks about TH instead of talking about my extension. | | I want to be able to format the error message header myself using | information like filename and line number that TH provides to me. | | 2) They contain a body generated by TH. | If the code my language extension generates is wrong, | there's virtually no chance that any user (myself included) | will figure it out from seeing the machine-generated Haskell | code or being given the type error message. | Better just to say there is a problem and leave it at that. | | I want to be able to construct the error message body myself | using information like the expression being spliced before | evaluation, after evaluation and the error message produced. | | | A related issue is that I generate files corresponding to each TH module I | compile. If ghc is producing a file called foo/bar.o, I'd like the name of | the file to be foo/bar_stub.o. For this sort of application, I need access | to the name of the input and output filenames. | | Finally, can you drop the 'tick' from variable names produced using gensym? | If you'd used underscore, the variable name would be a legal C identifier | too. (Ok, so this is a bit specialized but it's very easy to do.) | | -- | Alastair Reid www.haskell-consulting.com |
f 0 = failWith "Postitive n required f n = [| \x -> x+n |] ....$(f 0).....
would elicit the error message
Foo.hs:8: Error in splice $(f 0): Positive n required
Is that what you want?
I'd like: 1) To be able to write the function that formats the error message. That is, the bit that adds in "Error in splice $(f 0):" Possible interface: --| Raise a TH exception -- First argument uses the splice string to produce -- an error string failWithEx :: (String -> Q String) -> Q a failWith msg = failWithEx (\ splice -> return ( "Error in splice " ++ splice ++ ":" ++ "\n" ++ msg) 2) To be able to catch errors resulting from compiling the spliced code. If we deliberately introduce an error: f n = [| \x -> x+'n' |] ....$(f 3).... we get this error message: Couldn't match `Int' against `Char' Expected type: Int Inferred type: Char In the second argument of `(+)', namely 'a' In a lambda abstraction: \ x'0 -> (x'0 + 'a') I'd like the option of replacing that message with: Foo.hs:8: Uncaught Template Greencard error while expanding '$(f 3)' Please report it as a bug The most obvious way to do this is to allow the exception to be caught. Possible interface: --| Though this has the type of a normal exception catching function, -- its semantics is (I think) a bit different because it catches -- exceptions triggered by splicing its first argument into the -- module and lets the handler offer up n alternative value to splice -- in. -- (For implementation reasons, it might be necessary to restrict -- its use to top-level splices? - I'm guessing that this is the only -- case where it's possible to unambiguously place the blame on -- the splice.) catchQ :: Q a -> (Exception -> Q a) -> Q a Using this, I'd rewrite f :: Int -> Q Exp f n = catchQ (\ ex -> failWithEx (\ splice -> return "Uncaught ...")) (f' n) f' 0 = failWith "Postitive n required f' n = [| \x -> x+n |] -- Alastair Reid www.haskell-consulting.com
participants (2)
-
Alastair Reid -
Simon Peyton-Jones