问题
I'm trying to learn some Template Haskell. As an exercise, I wrote a function that can generate things like isLeft
and isRight
(inspired by this question). Here's my humble attempt:
isA connam = do
ConE nam <- connam
nn <- newName "p"
lamE [varP nn] $ caseE (varE nn) [
match (conP nam [wildP]) ( normalB [| True |] ) [],
match wildP ( normalB [| False |] ) []
]
The problem is that I have to write $(isA [| Left |])
instead of the more intuitive isA Left
. Is it possible to get rid of the ugly syntax? I can't seem to find the answer in the documentation.
The function only works with one-argument constructors, but this is for another question.
回答1:
The syntax is there for a reason; to inform the reader that there is compile-time magic going on here. You can only eliminate the $(...)
when your splice is at the top level.
However, we can eliminate the [| ... |]
and also make the code more type-safe by taking in a Name
instead of an Exp
:
isA nam = do
nn <- newName "p"
lamE [varP nn] $ caseE (varE nn) [
match (conP nam [wildP]) ( normalB [| True |] ) [],
match wildP ( normalB [| False |] ) []
]
To use this, you'd write $(isA 'Left)
, which is a little easier on the eyes.
As a bonus, if you try giving it something other than a Name
, you get a type error instead of an irrefutable pattern match error.
See also: Template Haskell Syntax
来源:https://stackoverflow.com/questions/7213938/how-to-get-rid-of-and-syntax-when-using-a-template-haskell-func