संक्षिप्त उत्तर यह है: पैटर्न मिलान के साथ यह संभव नहीं है, आपको एक फ़ंक्शन का उपयोग करना होगा।
लंबा उत्तर यह है: यह मानक हास्केल में नहीं है, लेकिन यदि आप व्यू पैटर्न नामक एक एक्सटेंशन का उपयोग करने के इच्छुक हैं, और यदि आपको अपने पैटर्न मिलान में कोई समस्या नहीं है तो अंततः निरंतर समय से अधिक समय लेना।
कारण यह है कि पैटर्न मिलान पहली जगह संरचना का निर्माण कैसे किया जाता है इस पर आधारित है।
data List a = Empty | Cons a (List a)
deriving (Show) -- this is just so you can print the List
आप की तरह है कि आप तीन वस्तुओं उत्पन्न एक प्रकार की घोषणा जब: एक प्रकार निर्माता List
, और दो डेटा कंस्ट्रक्टर्स: Empty
और Cons
सूची एक सार प्रकार है, जो निम्नलिखित संरचना है। प्रकार का कन्स्ट्रक्टर प्रकार लेता है और उन्हें अन्य प्रकारों में बदल देता है, यानी List
एक प्रकार a
लेता है और एक और प्रकार List a
बनाता है। डेटा कन्स्ट्रक्टर एक ऐसे फ़ंक्शन की तरह काम करता है जो List a
प्रकार का कुछ देता है। इस मामले में आप हैं:
Empty :: List a
एक खाली सूची और
Cons :: a -> List a -> List a
किस प्रकार a
और एक सूची के एक मूल्य लेता है और सूची के सिर के लिए मूल्य जोड़ देती है, एक और सूची लौटने का प्रतिनिधित्व। तो अगर आप इस तरह अपनी सूची का निर्माण कर सकते हैं:
empty = Empty -- similar to []
list1 = Cons 1 Empty -- similar to 1:[] = [1]
list2 = Cons 2 list1 -- similar to 2:(1:[]) = 2:[1] = [2,1]
यह कम या ज्यादा कैसे सूचियों के काम है, लेकिन Empty
के स्थान पर आप []
है और Cons
के स्थान पर आप (:)
है।जब आप [1,2,3]
जैसे कुछ टाइप करते हैं तो यह 1:2:3:[]
या Cons 1 (Cons 2 (Cons 3 Empty))
के लिए सिंटैक्टिक चीनी है।
जब आप पैटर्न मिलान करते हैं, तो आप इस प्रकार को "डी-कंस्ट्रक्शन" कर रहे हैं। किस प्रकार संरचित किया गया है, इस बारे में ज्ञान रखने से आप इसे विशिष्ट रूप से अलग कर सकते हैं। फ़ंक्शन पर विचार करें:
head :: List a -> a
head (Empty) = error " the empty list have no head"
head (Cons x xs) = x
टाइप मिलान पर क्या होता है यह है कि डेटा कन्स्ट्रक्टर आपके द्वारा दी गई कुछ संरचनाओं से मेल खाता है। यदि आपके पास खाली सूची होने की तुलना में Empty
से मेल खाता है। यदि मेल खाता है Const x xs
तो x
प्रकार a
होना आवश्यक है और सूची के सिर होना चाहिए और xs
प्रकार List a
है और सूची की पूंछ होना चाहिए, कि डेटा निर्माता के प्रकार है कारण:
Cons :: a -> List a -> List a
हैं Cons x xs
x
से List a
प्रकार a
और xs
List a
होना चाहिए। वही सच है (x: xs)। आप GHCi में की (:) प्रकार के लिए तत्पर हैं:
> :t (:)
(:) :: a -> [a] -> [a]
तो, अगर (एक्स: XS) प्रकार [a]
की है, x
a
होना चाहिए और xs
[a]
होना चाहिए। जब आप (xs:x)
करने का प्रयास करते हैं तो त्रुटि संदेश मिलता है और फिर xs
किसी सूची की तरह व्यवहार करता है, ठीक इसी कारण है। (:)
के उपयोग से कंपाइलर अनुमान लगाता है कि xs
टाइप a
है, और के उपयोग से, यह अनुमान लगाता है कि xs
[a]
होना चाहिए। फिर यह बाहर निकलता है क्योंकि कोई सीमित प्रकार a
नहीं है जिसके लिए a = [a]
- यही वह है जो वह आपको उस त्रुटि संदेश के बारे में बताने की कोशिश कर रहा है।
यदि आपको अन्य तरीकों से संरचना को अलग करने की आवश्यकता है जो डेटा कन्स्ट्रक्टर संरचना के निर्माण के तरीके से मेल नहीं खाता है, तो आपको अपना स्वयं का फ़ंक्शन लिखना होगा। मानक लाइब्रेरी में दो कार्य हैं जो आप चाहते हैं: last
किसी सूची का अंतिम तत्व देता है, और init
सूची के सभी-अंतिम-अंतिम तत्व लौटाता है।
लेकिन ध्यान दें कि पैटर्न मिलान निरंतर समय में होता है। सूची और सूची की पूंछ का पता लगाने के लिए, इससे कोई फ़र्क नहीं पड़ता कि सूची कितनी देर तक है, आपको केवल बाहरी डेटा कन्स्ट्रक्टर को देखना होगा। अंतिम तत्व ढूंढना O(N)
है: जब तक आपको सबसे कम Cons
या सबसे कम (:)
नहीं मिल जाता है, तब तक आपको खुदाई करनी होगी, और इसके लिए आपको एन बार संरचना "छील" की आवश्यकता होती है, जहां एन सूची का आकार है।
यदि आपको अक्सर लंबी सूचियों में अंतिम तत्व देखना है, तो आप शायद इस बात पर विचार कर सकते हैं कि सूची का उपयोग करना एक अच्छा विचार है। (पहले और अंतिम तत्वों तक निरंतर समय तक पहुंच), Data.Map
(log(N)
यदि आप इसकी कुंजी जानते हैं तो किसी भी तत्व के लिए समय पहुंच), Data.Array
(यदि आप इसकी अनुक्रमणिका जानते हैं तो तत्व के निरंतर समय तक पहुंच) Data.Vector
या अन्य डेटा संरचनाओं की तुलना में आपकी आवश्यकताओं से मेल खाने वाली संरचनाएं।
ठीक है। वह छोटा जवाब था (: पी)। लंबे समय तक आपको खुद को थोड़ा सा देखना होगा, लेकिन यहां एक परिचय है।
आप इसे दृश्य पैटर्न का उपयोग कर पैटर्न मिलान के बहुत करीब एक वाक्यविन्यास के साथ काम कर सकते हैं।पैटर्न देखें एक विस्तार है कि आप अपने कोड की पहली पंक्ति के रूप में इस होने से उपयोग कर सकते हैं:
{-# Language ViewPatterns #-}
कि यह कैसे उपयोग करने के लिए के निर्देश यहां हैं: http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns
आप की तरह कुछ कर सकता है दृश्य पैटर्न के साथ
: x
view :: [a] -> (a, [a])
view xs = (last xs, init xs)
someFunction :: [a] -> ...
someFunction (view -> (x,xs)) = ...
से और xs
last
और सूची आप someFunction
करने के लिए प्रदान की init
के लिए बाध्य होंगे। संवैधानिक रूप से यह पैटर्न मिलान की तरह लगता है, लेकिन यह वास्तव में दिए गए सूची में last
और init
लागू कर रहा है।
यदि आपको सूची की पूंछ की आवश्यकता है तो आप अपनी समस्या के लिए गलत डेटा संरचना का उपयोग कर रहे हैं। एक पेड़, dlist, अनुक्रम या अन्य संरचना पर विचार करें। –