2015-01-22 13 views
8

के लेंस लाइब्रेरी में ix और तत्व के बीच अंतर क्या है हास्केल की लेंस लाइब्रेरी में, ix और element दोनों एक इंट का उपयोग किया जा सकता है उदा। पढ़ने के लिए या कुछ सूचकांक एक सूची तत्व लिखते हैं, इसहास्केल

ghci> [1..10] ^? ix 4 
Just 5 
ghci> [1..10] & ix 4 .~ 1 
[1,2,3,4,1,6,7,8,9,10] 

और इसी तरह करने के लिए:

ghci> [1..10] ^? element 4 
Just 5 
ghci> [1..10] & element 4 .~ 1 
[1,2,3,4,1,6,7,8,9,10] 

element और ix के बीच क्या अंतर है?

उत्तर

11

ix के साथ आप न केवल संख्या के आधार पर इंडेक्स कर सकते हैं, लेकिन उदा। मानचित्र में कुंजी। element सूचकांक Traverse क्रम में।

λ> let m = Map.fromList [("foo", 'f'), ("bar", 'b')] 
λ> m ^? ix "foo" 
Just 'f' 

λ> m ^? element 0 -- Map is ordered container! 
Just 'b' 

अंतर के साथ और भी स्पष्ट है IntMap

λ> let im = IntMap.fromList [(1, "one"), (2, "two")] 
λ> im ^? ix 1 
Just "one" 
λ> im ^? element 1 
Just "two" 
4

elementTraversable वर्ग, यहां तक ​​कि वर्ग के सदस्यों जो लेंस पुस्तकालय के बारे में पता नहीं है के प्रकार के साथ काम करने के लिए परिभाषित किया गया है। इस प्रकार यह मूल्य तक पहुंचने के लिए केवल Traversable फ़ंक्शंस का उपयोग करता है, जिसमें मूल्य के प्रकार के लिए विशिष्ट किसी भी इंडेक्स प्रकार की कोई अवधारणा नहीं है। इस प्रकार, केवल Int सूचकांक समर्थित हैं, सामान्य ट्रैवर्सल ऑर्डर में तत्व देते हैं।

element भी IndexedTraversal देता है, जो सूचकांक को संभालने के कुछ अतिरिक्त तरीके प्रदान करता है।

ix केवल लेंस लाइब्रेरी के बारे में जानता है, लेकिन इसके बदले में यह मूल्य के प्रकार पर निर्भर विभिन्न इंडेक्स प्रकारों का उपयोग कर सकता है।

सूचियों के लिए वे एक ही परिणाम देते हैं। लेकिन अंतर देखा जा सकता है उदा। Data.Map के लिए:

Prelude Control.Lens Data.Map> singleton "a" 3 ^? element "a" 

<interactive>:19:28: 
    Couldn't match expected type ‘Int’ with actual type ‘[Char]’ 
    In the first argument of ‘element’, namely ‘"a"’ 
    In the second argument of ‘(^?)’, namely ‘element "a"’ 
    In the expression: singleton "a" 3 ^? element "a" 

Prelude Control.Lens Data.Map> singleton "a" 3 ^? ix "a" 
Just 3 
Prelude Control.Lens Data.Map> singleton "a" 3 ^? element 0 
Just 3 
Prelude Control.Lens Data.Map> singleton "a" 3 ^? ix 0 

<interactive>:22:23: 
    Could not deduce (Num [Char]) arising from the literal ‘0’ 
    from the context (Num a) 
     bound by the inferred type of it :: Num a => Maybe a 
     at <interactive>:22:1-23 
    In the first argument of ‘ix’, namely ‘0’ 
    In the second argument of ‘(^?)’, namely ‘ix 0’ 
    In the expression: singleton "a" 3 ^? ix 0 

आप देख सकते हैं, element के साथ नक्शा Int सूचकांक, यह देखते हुए, जबकि ix साथ यह सूचकांक के रूप में कुंजी प्रकार दिया जाता है, और स्विच करने के लिए है कि एक प्रकार त्रुटि देता है चारों ओर कर रहा है।

3

element एक संपूर्ण संरचना चलने, तत्वों की गिनती करके और लक्ष्य सूचकांक के साथ तत्व को घुमाने के द्वारा काम करता है। इसलिए यह हमेशा संरचना के आकार में समय जटिलता ओ (एन) है, और यह केवल Int सूचकांक के साथ काम करता है।

इसके विपरीत, ix की अपनी कक्षा Ixed है, और उदाहरण विशिष्ट डेटा संरचनाओं के लुकअप/संशोधित संचालन पर भरोसा करते हैं। उदाहरण के लिए, ixData.Sequence के लिए ओ (लॉग एन) है।

हालांकि, ix केवल विशिष्ट डेटा संरचनाओं पर, काम करता है, जबकि किसी भी Traversal, Lens या Iso साथ elementOf काम करता है, उदाहरण के लिए:

[0..10] ^? elementOf (reversed . each . filtered odd) 1 
-- Just 7 
+0

धन्यवाद। जटिलता का जिक्र करने के लिए +1, मैं वास्तव में इसके बारे में चिंतित था। यह कुल समझ में आता है। तो ऐसा लगता है कि हमें जहां संभव हो ix का उपयोग करना चाहिए। – Stephan