2011-12-14 17 views
7

मैं हास्केल में ऐसा कुछ करना चाहता हूं, लेकिन संकलक मुझे नहीं दे रहा है।गतिशील मॉड्यूल नाम

क्या इस कार्य को पूरा करने का कोई तरीका है?

-- both modules export function named "hello" 
-- and I want to run it in every module 
import qualified MyMod as M1 
import qualified MyAnotherMod as M2 

runmodules = map (\m -> m.hello) [M1, M2] 
+0

क्या हल करने के लिए समस्या आप चाहते है? चूंकि फ़ंक्शन का नाम ज्ञात है (हैलो), क्यों न केवल फ़ंक्शंस को '[M1.hello, M2.hello]' में डालें और उस सूची के साथ कुछ करें? मुझे लगता है कि आप किसी भी तरह टेम्पलेट हास्केल के साथ प्राप्त कर सकते हैं, लेकिन यह अत्यधिक जटिल हो सकता है। – bzn

उत्तर

5

मुझे नहीं लगता कि आप टेम्पलेट हास्केल में ऐसे ही एक योग्य नाम उपसर्ग बोली सकते हैं, और hello पहचानकर्ता ताकि आप तार के साथ प्रोग्रामिंग में वापस आने का हो सकता है, दायरे में नहीं है।

module ModuleParamsTH where 
import Language.Haskell.TH 

getAll :: String -> [String] -> ExpQ 
getAll valueName moduleNames = 
    listE $ map (varE . mkName . (++ suffix)) moduleNames 
    where suffix = "." ++ valueName 

जो तब तो की तरह इस्तेमाल किया जा सकता है,

{-# LANGUAGE TemplateHaskell #-} 
import ModuleParamsTH 
import qualified ModuleParamsM1 as M1 
import qualified ModuleParamsM2 as M2 

runmodules = $(getAll "hello" ["M1", "M2"]) 

हालांकि, मैं यह सब नहीं होता। आप केवल [M1.hello, M2.hello] लिख सकते हैं या कार्यान्वयन पर सार के लिए एक प्रकार का वर्ग उपयोग कर सकते हैं।

3

मॉड्यूल हास्केल में मूल्य नहीं हैं। इसलिए यह संभव नहीं है। आपकी क्या प्राप्त करने की इच्छा है?

8

हास्केल में मॉड्यूल दूरस्थ तरीके से प्रथम श्रेणी की इकाइयां भी नहीं हैं जिनकी आवश्यकता होगी, मुझे डर है।

हालांकि, जैसा कि बीजेएन ने टिप्पणी की, Template Haskell इस तरह की समस्याओं के लिए उपयोग किया जा सकता है। नतीजा थोड़ा बेकार हो सकता है, लेकिन अगर आपको वास्तव में कुछ त्वरित मेटाप्रोग्रामिंग हैक्स की आवश्यकता है तो यह एक खराब विकल्प नहीं है। मैं वास्तव में टी के साथ एक विशेषज्ञ नहीं हूं, लेकिन आप जो चाहते हैं वह बहुत आसान है, एक पकड़ के साथ: न तो "संदिग्ध पहचानकर्ता" और न ही "मॉड्यूल नाम" किसी भी तरह से कब्जा या उद्धृत किया जा सकता है, जहां तक ​​मुझे पता है, तो आप ' उन्हें TH फ़ंक्शन में तर्क के रूप में दिए गए तारों में रखना होगा।

यहाँ एक त्वरित और गंदी, कम से कम उदाहरण है:

{-# LANGUAGE TemplateHaskell #-} 
module MapModuleTH where 

import Language.Haskell.TH 

mapQual :: [String] -> String -> ExpQ 
mapQual ms n = listE $ map (\m -> varE . mkName $ m ++ "." ++ n) ms 

mapMQual :: [String] -> String -> ExpQ 
mapMQual ms n = appE (varE 'sequence) $ listE $ map (\m -> varE . mkName $ m ++ "." ++ n) ms 

आप के रूप में जो अधिक IO कार्यों, बस सामान की एक सूची एकत्र नहीं कर का एक समूह कर की तरह लगता है "समारोह चल रहा है" बातें phrased, तो मैं एक संस्करण जोड़ा जो परिणाम को भी अनुक्रमित करता है।

नोट यहां तार के उपयोग के बावजूद, इस अभी भी स्थिर टाइप किया है कि, - अगर योग्य नाम मौजूद नहीं है, या प्रकार से मेल नहीं है, आप की उम्मीद संकलन समय मिल जाएगा त्रुटि जैसे कि आप सब कुछ हाथ से बाहर लिखा होगा।

यहां इसका उपयोग करने का एक त्वरित उदाहरण है। निम्नलिखित को देखते हुए:

{-# LANGUAGE TemplateHaskell #-} 
module MapModule where 

import MapModuleTH 
import qualified Test1 as T1 
import qualified Test2 as T2 

tests = do xs <- $(mapMQual ["T1", "T2"] "test") 
      putStrLn $ "Count: " ++ show (length xs) 

मान लिया जाये कि अन्य मॉड्यूल देखते हैं और test परिभाषित करते हैं, तो GHCi में हम देख सकते हैं:

> tests 
Test 1 
Test 2 
Count: 2 
संबंधित मुद्दे