मैं एक स्टैब ले जाऊंगा, हालांकि TH को और कोड देखने के बिना डीबग करना मुश्किल हो सकता है।
foo.hs:
{-# Language TemplateHaskell #-}
baz x = let f y = x + y
in [| f |]
bez x = let f y = x + y
in [| \y -> f y |]
boz x = [| \y -> x + y |]
g x y = x + y
byz x = [| g x |]
अब हम (मैं संस्करण 7.0.2 पर हूँ, जो GHCi में इस सक्रिय कर सकता है
के कुछ नमूना कोड पर एक नज़र डालते हैं क्या वर्तमान हास्केल मंच) के साथ जहाजों:
$ ghci foo.hs -XTemplateHaskell
*Main> :m +Language.Haskell.TH
*Main Language.Haskell.TH> runQ (baz 2)
<interactive>:1:7:
No instance for (Language.Haskell.TH.Syntax.Lift (a0 -> a0))
arising from a use of `baz'
Possible fix:
add an instance declaration for
(Language.Haskell.TH.Syntax.Lift (a0 -> a0))
In the first argument of `runQ', namely `(baz 2)'
In the expression: runQ (baz 2)
In an equation for `it': it = runQ (baz 2)
*Main Language.Haskell.TH> runQ (bez 2)
<interactive>:1:7:
No instance for (Language.Haskell.TH.Syntax.Lift (a0 -> a0))
arising from a use of `bez'
Possible fix:
add an instance declaration for
(Language.Haskell.TH.Syntax.Lift (a0 -> a0))
In the first argument of `runQ', namely `(bez 2)'
In the expression: runQ (bez 2)
In an equation for `it': it = runQ (bez 2)
*Main Language.Haskell.TH> runQ (boz 2)
LamE [VarP y_0] (InfixE (Just (LitE (IntegerL 2))) (VarE GHC.Num.+) (Just (VarE y_0)))
*Main Language.Haskell.TH> runQ (byz 2)
AppE (VarE Main.g) (LitE (IntegerL 2))
मैं यहाँ क्या किया है runQ
उपयोग करने के लिए वें जोड़ च कैसा दिखता है करने का प्रयास किया है या नमूना कोड में मेरे प्रत्येक कार्य। यह baz
और bez
पर विफल रहता है, लेकिन boz
और byz
के लिए काम करता है।
boz
और byz
के लिए वें को देखते हुए, हम देख सकते हैं कि कार्यों को उठा लिया जाता है: boz
मूल रूप से सिर्फ नाम से +
की चर्चा करते हुए किया जाता है (VarE GHC.Num.+
में) है, जबकि byz
सिर्फ नाम से g
की चर्चा करते हुए किया जाता है (VarE Main.g
में)।
baz
और bez
के लिए, यह विकल्प तालिका पर नहीं है: दोनों कार्य f
को विभाजित करने का प्रयास कर रहे हैं, जो स्थानीय रूप से बाध्य है; इसलिए, VarE f
का संदर्भ baz
और bez
के बाहर समझ में नहीं आता है।
तो डेवलपर क्या करना है? संक्षेप में, [| f |]
को आजमाने की बजाय, आपको लिफ्ट में सीधे f
के लिए अभिव्यक्ति लिखनी होगी, पहचानकर्ताओं के संदर्भ में जो विभाजन होगा जहां विभाजन होगा।
एक तरफ ध्यान दें, बीजगणितीय डेटा प्रकारों के लिए Lift
उदाहरण लिखना बहुत आसान है, क्योंकि आप हमेशा विश्व स्तर पर परिभाषित कार्यों को उठा सकते हैं।
instance Lift a => Lift (Maybe a) where
lift Nothing = [| Nothing |]
lift (Just a) = [| Just a |]
मैं [डॉक्स] पाया है (http://hackage.haskell.org/packages/archive/template-haskell/2.4.0.1/doc/html/Language-Haskell-TH: यहाँ
Maybe
के लिए एक है -Syntax.html # टी: लिफ्ट) (लगभग कोई नहीं)। उम्मीद है कि यह मदद करता है, लेकिन शायद यह नहीं होगा :(ऐसा लगता है कि आपको एक समारोह 'लिफ्ट :: (स्ट्रिंग -> [सामग्री]) -> क्यू एक्सप' लिखना है, यानी, अपने फ़ंक्शन को अभिव्यक्ति में अनुवादित करें। –