तरह से आप अपने कोड लिखा है, संकलन समय पर कोई मूल्यांकन नहीं होगा। जब आप [| ... |]
के साथ एक हास्केल अभिव्यक्ति बोली, उद्धृत कोड/एएसटी डाला जाता है जहां आप इसे किसी भी मूल्यांकन के बिना लागू होते हैं, तो लेखन:
$(hString "hello, world")
लेखन के रूप में बिल्कुल वैसा ही है:
let s = "hello, world" in HashString (hash $ T.pack s) (T.pack s)
लेकिन लगता है इसके बारे में: आप [| ... |]
का उपयोग बाद में सम्मिलित होने वाली अभिव्यक्ति को उद्धृत करने के लिए करते हैं, और आप $(...)
के साथ संकलन-समय पर कोड उत्पन्न करते हैं। इसलिए, यदि आप उद्धृत अभिव्यक्ति bla = [| bar $(foo) |]
में कुछ कोड $(foo)
शामिल करते हैं, तो $(bla)
कोड bar $(foo)
उत्पन्न करेगा, जो बदले में foo
संकलन समय पर मूल्यांकन करेगा। साथ ही, संकलन समय पर उत्पन्न होने वाले मान को लेने और उससे अभिव्यक्ति उत्पन्न करने के लिए, आप lift
फ़ंक्शन का उपयोग करते हैं। तो, क्या आप क्या करना चाहते है:
import Data.String (fromString)
import Language.Haskell.TH.Syntax
hString s = [| HashString $(lift . hash . T.pack $ s) (fromString s) |]
यह संकलन समय पर हैश फंक्शन का मूल्यांकन करता है, के बाद से आंतरिक जोड़ के बाद बाहरी जोड़ हल किया गया था हल हो गई है। वैसे, Data.String
से fromString
का उपयोग से कुछ OverloadedString
डेटा प्रकार बनाने का सामान्य तरीका है।
इसके अलावा, आपको अपने HashString
इंटरफ़ेस के लिए अर्ध-उद्धरण बनाने पर विचार करना चाहिए। अर्ध-उद्धरण का उपयोग मैन्युअल रूप से स्प्लिस फ़ंक्शंस को कॉल करने से अधिक प्राकृतिक है (और आप पहले ही उनका उपयोग कर चुके हैं; नामहीन [| ... |]
उद्धरण उद्धरण हास्केल अभिव्यक्तियां)।
आप इस प्रकार का quasiquoter बनाना होगा:
import Language.Haskell.TH.Quote
hstr =
QuasiQuoter
{ quoteExp = hString -- Convenient: You already have this function
, quotePat = undefined
, quoteType = undefined
, quoteDec = undefined
}
यह जाने हैं तो आप इस वाक्य रचना के साथ HashString
रों लिखें:
{-# LANGUAGE QuasiQuotes #-}
myHashString = [hstr|hello, world|]
बहुत बढ़िया जवाब! धन्यवाद। –