记录QuasiQuoter构造函数的语法

use*_*220 3 haskell template-haskell

模板Haskell 的文档QuasiQuoter定义为

data QuasiQuoter = QuasiQuoter { quoteExp  :: String -> Q Exp,
                                 quotePat  :: String -> Q Pat,
                                 quoteType :: String -> Q Type,
                                 quoteDec  :: String -> Q [Dec] }
Run Code Online (Sandbox Code Playgroud)

我遇到过silly如下所示的例子.他们如何工作因为他们似乎并没有填写quotePat,quoteTypequoteDec领域?

silly :: QuasiQuoter
silly = QuasiQuoter { quoteExp = \_ -> [| "yeah!!!" |] }
Run Code Online (Sandbox Code Playgroud)

use*_*038 5

答案与TH无关:如果您没有初始化记录构造函数的字段,尝试访问该字段将导致错误:

>data D = D {a :: Int, b :: Char} deriving Show
>D {a = 0}
D {a = 0, b = *** Exception: <interactive>:26:1-9: Missing field in record construction :Interactive.b
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这是期望的行为,因为某些引用仅在某个上下文中有意义,并且如果它们被不正确地使用则应该抛出错误.虽然,您很可能希望为您的报价者提供更具描述性的错误消息,例如:

quote = QuasiQuoter { 
   quoteExp = something, 
   quotePat = error "quote: Invalid application in pattern context." ....
Run Code Online (Sandbox Code Playgroud)