2011-08-27 28 views
12

我想學習一些模板哈斯克爾。作爲練習,我寫了一個函數,可以生成諸如isLeftisRight(受this question啓發)。這是我謙虛的嘗試:

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。是否有可能擺脫醜陋的語法?我似乎無法在文檔中找到答案。

該函數僅適用於單參數構造函數,但是這是another question

回答

10

語法是有原因的;通知讀者這裏有編譯時間的魔法。當您的接頭處於頂層時,您只能消除$(...)

但是,我們可以消除[| ... |],也使代碼更類型安全通過採取的Name而不是Exp

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

要使用此,你會寫$(isA 'Left),這是一個在眼睛上輕鬆一點。

作爲獎勵,如果您嘗試給它以外的東西,而不是Name,您會得到一個類型錯誤,而不是無可辯駁的模式匹配錯誤。

另請參閱:Template Haskell Syntax

+0

謝謝。我絕對可以忍受這一點。我記得在某處讀到'$'不再是拼接所必需的,但我不確定它在什麼環境下,或者它是否可以在這裏應用。 –

+0

@ n.m。我剛纔在我的回答中加上了:)我猜你在寫評論時仍然在查看我的原始答案。 – hammar

+0

aha,所以如果我想讓'isA'Left'生成一個名爲'isALeft'的函數聲明而不是實際的函數,我可以省略$,對嗎? –