12

我正在尝试学习一些模板 Haskell。作为练习,我编写了一个函数,可以生成isLeft和(受此问题isRight启发)之类的东西。这是我卑微的尝试:

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 |] ) [] 
                     ]

问题是我必须写$(isA [| Left |])而不是更直观isA Left。是否有可能摆脱丑陋的语法?我似乎无法在文档中找到答案。

该函数仅适用于单参数构造函数,但这是另一个问题

4

1 回答 1

11

语法是有原因的;告诉读者这里有编译时魔法。您只能$(...)在接头位于顶层时消除。

但是,我们可以通过使用 a而不是a 来消除[| ... |]并且使代码更加类型安全:NameExp

isA nam = do
    nn <- newName "p"
    lamE [varP nn] $ caseE (varE nn) [
                       match (conP nam [wildP]) ( normalB [| True |] ) [],
                       match wildP ( normalB [| False |] ) [] 
                     ]

要使用它,你会写$(isA 'Left),这对眼睛来说更容易一些。

作为奖励,如果你尝试给它一个不是 a 的东西Name,你会得到一个类型错误而不是一个无可辩驳的模式匹配错误。

另请参阅:模板 Haskell 语法

于 2011-08-27T12:24:01.783 回答