जवाबों:
देखो यहाँ , इस्तेमाल किया ऑपरेटर है !!।
Ie [1,2,3]!!1आपको देता है 2, क्योंकि सूची 0-अनुक्रमित हैं।
itemOf :: Int -> [a] -> Maybe a; x `itemOf` xs = let xslen = length xs in if ((abs x) > xslen) then Nothing else Just (xs !! (x `mod` xslen))। ध्यान दें, यह अनन्त सूची में विनाशकारी रूप से विफल हो जाएगा।
!!एक आंशिक और इस प्रकार असुरक्षित कार्य है। नीचे टिप्पणी पर एक नज़र डालें और lens stackoverflow.com/a/23627631/2574719
मैं यह नहीं कह रहा हूं कि आपके प्रश्न या दिए गए उत्तर में कुछ भी गलत है, लेकिन शायद आप उस अद्भुत टूल के बारे में जानना चाहेंगे जो भविष्य में खुद को बचाने के लिए Hoogle है: Hoogle के साथ, आप मानक लाइब्रेरी फ़ंक्शंस की खोज कर सकते हैं वह किसी दिए गए हस्ताक्षर से मेल खाता है। इसलिए, !!अपने मामले में कुछ भी नहीं जानने के बाद , आप "कुछ ऐसी चीज़ों की खोज कर सकते हैं जो व्हाट्सएप की Intएक सूची लेती है और एक भी रिटर्न देता है"
Int -> [a] -> a
लो और निहारना , !!पहले परिणाम के रूप में (हालांकि प्रकार के हस्ताक्षर में वास्तव में दो तर्क हैं जो हमने खोजा था उसकी तुलना में उल्टा है)। नीट, हुह?
इसके अलावा, यदि आपका कोड अनुक्रमणिका पर निर्भर करता है (सूची के सामने से उपभोग करने के बजाय), सूची वास्तव में उचित डेटा संरचना नहीं हो सकती है। O (1) अनुक्रमणिका-आधारित पहुँच के लिए अधिक कुशल विकल्प हैं, जैसे सरणियाँ या वैक्टर ।
उपयोग का एक विकल्प (!!)का उपयोग है
लेंस पैकेज और उसके elementसमारोह और संबद्ध ऑपरेटरों।
लेंस के ऊपर और सूचियों से परे संरचनाओं और नेस्टेड संरचनाओं की एक विस्तृत विविधता तक पहुँचने के लिए एक समान अंतरफलक प्रदान करता है। नीचे मैं उदाहरण प्रदान करने पर ध्यान केंद्रित करूंगा और लेंस पैकेज के पीछे दोनों प्रकार के हस्ताक्षर और सिद्धांत पर चमक दूंगा
। यदि आप सिद्धांत के बारे में अधिक जानना चाहते हैं तो शुरू करने के लिए एक अच्छी जगह है गिथब रेपो ।
कमांड लाइन पर:
$ cabal install lens
$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
> import Control.Lens
इन्फिक्स ऑपरेटर के साथ एक सूची का उपयोग करने के लिए
> [1,2,3,4,5] ^? element 2 -- 0 based indexing
Just 3
इसके विपरीत (!!)एक तत्व को सीमा से बाहर पहुंचने पर अपवाद नहीं फेंकेगा और Nothingइसके बजाय वापस आ जाएगा। यह अक्सर की तरह आंशिक कार्यों से बचने के लिए सलाह देते हैं है (!!)या headके बाद से वे और अधिक कोने मामलों है और अधिक एक रन समय त्रुटि का कारण होने की संभावना है। आप इस विकी पृष्ठ पर आंशिक कार्यों से बचने के बारे में थोड़ा और पढ़ सकते हैं ।
> [1,2,3] !! 9
*** Exception: Prelude.(!!): index too large
> [1,2,3] ^? element 9
Nothing
आप लेंस तकनीक को एक आंशिक फ़ंक्शन होने के लिए बाध्य कर सकते हैं और (^?!)ऑपरेटर के बजाय ऑपरेटर का उपयोग करके सीमा से बाहर होने पर एक अपवाद फेंक सकते हैं (^?)।
> [1,2,3] ^?! element 1
2
> [1,2,3] ^?! element 9
*** Exception: (^?!): empty Fold
यह सिर्फ सूचियों तक ही सीमित नहीं है। उदाहरण के लिए एक ही तकनीक मानक कंटेनरों के पैकेज से पेड़ों पर काम करती है ।
> import Data.Tree
> :{
let
tree = Node 1 [
Node 2 [Node 4[], Node 5 []]
, Node 3 [Node 6 [], Node 7 []]
]
:}
> putStrLn . drawTree . fmap show $tree
1
|
+- 2
| |
| +- 4
| |
| `- 5
|
`- 3
|
+- 6
|
`- 7
अब हम पहले-पहले क्रम में पेड़ के तत्वों तक पहुँच सकते हैं:
> tree ^? element 0
Just 1
> tree ^? element 1
Just 2
> tree ^? element 2
Just 4
> tree ^? element 3
Just 5
> tree ^? element 4
Just 3
> tree ^? element 5
Just 6
> tree ^? element 6
Just 7
हम कंटेनर पैकेज से अनुक्रमों तक भी पहुंच सकते हैं :
> import qualified Data.Sequence as Seq
> Seq.fromList [1,2,3,4] ^? element 3
Just 4
हम वेक्टर पैकेज से मानक int अनुक्रमित सरणियों का उपयोग कर सकते हैं , मानक पाठ पैकेज से पाठ , मानक bytestring पैकेज और कई अन्य मानक डेटा संरचनाओं को बाइटस्ट्रेस्ट करते हैं। एक्सेस के इस मानक तरीके को आपकी व्यक्तिगत डेटा संरचनाओं तक बढ़ाया जा सकता है, जिससे उन्हें टाइपकास्ट टावर्सबल का एक उदाहरण बना दिया जा सकता है , उदाहरण के लिए Lens प्रलेखन में ट्रेवर्सेबल्स की लंबी सूची देखें । ।
नेस्टेड संरचनाओं में नीचे खोदना लेंस हैकेज के साथ सरल है । उदाहरण के लिए सूची की सूची में एक तत्व तक पहुँचने के लिए:
> [[1,2,3],[4,5,6]] ^? element 0 . element 1
Just 2
> [[1,2,3],[4,5,6]] ^? element 1 . element 2
Just 6
यह संरचना तब भी काम करती है जब नेस्टेड डेटा संरचनाएं विभिन्न प्रकार की होती हैं। इसलिए उदाहरण के लिए अगर मेरे पास पेड़ों की सूची थी:
> :{
let
tree = Node 1 [
Node 2 []
, Node 3 []
]
:}
> putStrLn . drawTree . fmap show $ tree
1
|
+- 2
|
`- 3
> :{
let
listOfTrees = [ tree
, fmap (*2) tree -- All tree elements times 2
, fmap (*3) tree -- All tree elements times 3
]
:}
> listOfTrees ^? element 1 . element 0
Just 2
> listOfTrees ^? element 1 . element 1
Just 4
जब तक वे Traversableआवश्यकता को पूरा करते हैं , तब तक आप मनमाने प्रकार से गहराई से घोंसला बना सकते हैं। इसलिए पाठ के दृश्यों के पेड़ों की सूची तक पहुंचना कोई पसीना नहीं है।
कई भाषाओं में एक सामान्य ऑपरेशन एक सरणी में अनुक्रमित स्थिति को असाइन करना है। अजगर में आप हो सकते हैं:
>>> a = [1,2,3,4,5]
>>> a[3] = 9
>>> a
[1, 2, 3, 9, 5]
लेंस पैकेज के साथ इस कार्यक्षमता देता है (.~)ऑपरेटर। हालांकि अजगर के विपरीत मूल सूची को उत्परिवर्तित नहीं किया जाता है, बल्कि एक नई सूची लौटा दी जाती है।
> let a = [1,2,3,4,5]
> a & element 3 .~ 9
[1,2,3,9,5]
> a
[1,2,3,4,5]
element 3 .~ 9सिर्फ एक फ़ंक्शन और (&)ऑपरेटर है, लेंस पैकेज का हिस्सा है
, बस रिवर्स फ़ंक्शन एप्लिकेशन है। यहां यह अधिक सामान्य फ़ंक्शन एप्लिकेशन के साथ है।
> (element 3 .~ 9) [1,2,3,4,5]
[1,2,3,9,5]
असाइनमेंट फिर से Traversableएस के मनमाने ढंग से घोंसले के शिकार के साथ पूरी तरह से ठीक काम करता है ।
> [[1,2,3],[4,5,6]] & element 0 . element 1 .~ 9
[[1,9,3],[4,5,6]]
Data.Traversableपुनः निर्यात करने के बजाय लिंक करने का सुझाव देना चाहिए lens?
सीधे जवाब पहले से ही दिया गया था: उपयोग करें !!।
हालाँकि, newbies अक्सर इस ऑपरेटर को अधिक इस्तेमाल करते हैं, जो हास्केल में महंगा है (क्योंकि आप एकल लिंक्ड सूची पर काम करते हैं, एरे पर नहीं)। इससे बचने के लिए कई उपयोगी तकनीकें हैं, सबसे आसान है जिप का इस्तेमाल। यदि आप लिखते हैं zip ["foo","bar","baz"] [0..], तो आपको एक जोड़ी में प्रत्येक तत्व के लिए "संलग्न" सूचकांकों के साथ एक नई सूची मिलती है: [("foo",0),("bar",1),("baz",2)]जो अक्सर आपकी आवश्यकता होती है।
हास्केल की मानक सूची डेटा प्रकार forall t. [t] कार्यान्वयन में एक कैनोनिकल सी लिंक्ड सूची से मिलती जुलती है, और इसके अनिवार्य गुण साझा करती है। लिंक की गई सूची सरणियों से बहुत अलग हैं। सबसे विशेष रूप से, एक O (1) निरंतर-समय ऑपरेशन के बजाय, अनुक्रमणिका द्वारा पहुंच O (n) रैखिक है।
यदि आपको लगातार यादृच्छिक पहुंच की आवश्यकता होती है, तो Data.Arrayमानक पर विचार करें ।
!!एक असुरक्षित आंशिक रूप से परिभाषित फ़ंक्शन है, जो आउट-ऑफ-द-रेंज सूचकांकों के लिए एक दुर्घटना को भड़काता है। ध्यान रखें कि मानक पुस्तकालय कुछ इस तरह के आंशिक कार्य (शामिल हो head, last, आदि)। सुरक्षा के लिए, एक विकल्प प्रकार Maybe, या Safeमॉड्यूल का उपयोग करें।
एक यथोचित कुशल, मजबूत कुल का उदाहरण (सूचकांकों के लिए index 0) अनुक्रमण समारोह:
data Maybe a = Nothing | Just a
lookup :: Int -> [a] -> Maybe a
lookup _ [] = Nothing
lookup 0 (x : _) = Just x
lookup i (_ : xs) = lookup (i - 1) xs
लिंक की गई सूचियों के साथ काम करना, अक्सर अध्यादेश सुविधाजनक होते हैं:
nth :: Int -> [a] -> Maybe a
nth _ [] = Nothing
nth 1 (x : _) = Just x
nth n (_ : xs) = nth (n - 1) xs
[1,2,3]!!6आपको एक रनटाइम त्रुटि देगा। यह बहुत आसानी से बचा जा सकता है अगर!!टाइप होता[a] -> Int -> Maybe a। हमारे पास हास्केल का बहुत ही कारण इस तरह की रनटाइम त्रुटियों से बचना है!