2011-05-17 42 views
6

निम्नलिखित परिदृश्य के लिए सबसे अच्छी डेटा संरचना क्या है?सूची बनाम मानचित्र (सभी तत्वों पर प्रमुख सुरक्षा बनाम मैपिंग)

कहो, आप यूआरएल

linkHaskell = Url "http://www.haskell.org" 
linkReddit = Url "http://www.reddit.com" 
... 

की एक सूची है और आप उन्हें व्यक्तिगत रूप से उपयोग करें, लेकिन आप भी उनमें से हैं, उदाहरण के सभी पर काम करना चाहते हैं लिंक की जांच, तो आप उन्हें एक सूची

allLinks = [ 
    linkHaskell 
    , linkReddit 
    ... 
    ] 

में डाल सकता है लेकिन उस त्रुटियां उत्पन्न हो सकती है, क्योंकि आप एक नया लिंक जोड़ने के लिए भूल जाते हैं हो सकता है।

आप उन यूआरएल को मानचित्र में स्टोर करना चुन सकते हैं, लेकिन फिर आप रनटाइम-त्रुटियों के लिए संकलन-समय त्रुटियों का आदान-प्रदान करेंगे, यदि आपके पास कुंजी में टाइपो हैं।

हास्केल में आप क्या करेंगे?

+1

यह संभव है एक नक्शा जिसका कुंजी एक और कर रहे हैं के लिए

एक और दृष्टिकोण कुछ खाका हास्केल जादू का उपयोग करने के लिए है डाटा प्रकार? (जिसके लिए आप डेटा कन्स्ट्रक्टर हास्केल, रेडडिट, और ऑर्ड का एक उदाहरण प्रदान करेंगे) क्या इससे अन्य समस्याओं का कारण बनता है? – Ptival

+0

शायद 'उदाहरण एनम यूआरएल जहां ...' मदद करता है? – phynfo

उत्तर

5

एक सरल दृष्टिकोण एक डेटाप्रकार लिंक के लिए, यानी

data Link = LinkHaskell | LinkReddit 
    deriving (Enum, Bounded) 

toUrl LinkHaskell = Url "http://www.haskell.org" 
toUrl LinkReddit = Url "http://www.reddit.org" 

allLinks :: [Link] 
allLinks = [minBound .. maxBound] 

तुम अब भी दो स्थानों पर नाम निर्दिष्ट करने के लिए है परिभाषित करने के लिए है, लेकिन कम से कम अब संकलक आप में इसे जोड़ने के लिए भूल जाते हैं शिकायत एक स्थान (कम से कम -Wall)। अब

{-# LANGUAGE TemplateHaskell #-} 

module Links where 

import Control.Monad 
import Language.Haskell.TH 

data Url = Url String 
    deriving (Show) 

mkLinks :: [(String, String)] -> Q [Dec] 
mkLinks links = liftM2 (++) mkAllLinks $ mapM mkLink links 
    where 
    mkLink (name, url) = valD (varP $ mkLinkName name) (normalB [| Url url |]) [] 
    mkAllLinks = [d| allLinks = $(listE [varE $ mkLinkName name | (name, _) <- links])|] 
    mkLinkName = mkName . ("link" ++) 

आप केवल एक ही स्थान पर लिंक का उल्लेख करने के लिए है:

{-# LANGUAGE TemplateHaskell #-} 

import Links 

mkLinks 
    [("Haskell", "http://www.haskell.org") 
    ,("Reddit", "http://www.reddit.org") 
    ,("StackOverflow", "http://www.stackoverflow.com") 
    ] 

main = do 
    putStrLn "By name:" 
    print $ linkHaskell 
    print $ linkReddit 

    putStrLn "All:" 
    mapM_ print allLinks 
+0

दिलचस्प, धन्यवाद। – LennyStackOverflow

संबंधित मुद्दे