2011-08-27 13 views
12

Bazı Şablon Haskell'i öğrenmeye çalışıyorum. Bir egzersiz olarak, isLeft ve isRight (this question'dan esinlenerek) gibi şeyler üretebilen bir işlev yazdım.

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

sorun yerine isA Left daha sezgisel bir $(isA [| Left |]) yazmak zorunda olmasıdır: Burada benim mütevazı bir girişim. Çirkin sözdizimden kurtulmak mümkün mü? Cevabı belgelerde bulamıyorum.

Bu işlev yalnızca bir argüman kurucularında çalışır, ancak bu another question içindir.

cevap

10

Sözdizimi bir neden var; okuyucuyu burada derleme zamanı sihirinin olduğu konusunda bilgilendirmek için. Eklemeniz en üst düzeyde olduğunda, yalnızca $(...)'u kaldırabilirsiniz.

Ancak, [| ... |] ortadan kaldırabilir ve ayrıca tip-güvenli kod daha bir Name yerine Exp bir içinde alarak olun:

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

bu kullanmak için, bir olduğunu $(isA 'Left), yazardım Gözlerde biraz daha kolay.

Bir bonus olarak, bir Name'dan başka bir şey vermeyi denerseniz, reddedilemez bir desen eşleme hatası yerine bir tür hatası alırsınız. Ayrıca bkz .:

+0

Teşekkürler. Bununla kesinlikle yaşayabilirim. Bir yerde okuduğumu hatırlıyorum, '$ 'artık eklemeler için gerekli değil, ama hangi bağlamda olduğundan emin değilim ya da burada geçerli olup olamayacağından emin değilim. –

+0

@ n.m. Bunu bir an önce cevapıma ekledim :) Sanırım yorumunuzu yazarken orijinal yanıtımı hala görüntülüyorsunuz. – hammar

+0

aha, bu yüzden eğer 'IS' gerçek işlev yerine 'isALeft 'adlı bir işlevin bildirimini oluşturmak için' Sol 'istiyorsa $' ı atlayabilirim, değil mi? –