[Template-haskell] RE: Template Haskell...

Alastair Reid alastair at reid-consulting-uk.ltd.uk
Thu Oct 30 10:04:45 EST 2003


> 	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



More information about the template-haskell mailing list