2015-09-02 4 views
8

मैंने अभी हास्केल सीखना शुरू कर दिया है और एक अजीब चीज पाई है।हास्केल में श्रेणियों का उपयोग करते समय मानचित्र एक अतिरिक्त तत्व क्यों लौटाता है?

ghci> [0,2..5] 
[0,2,4] 

यह 3 तत्व हैं:

Let हम एक सूची है। जब मैं इस सूची के साथ map का उपयोग मैं आउटपुट के रूप में 3 तत्व मिलता है, उदाहरण के लिए:

ghci> map (+ 1) [0,2..5] 
[1,3,5] 
ghci> map (* 2) [0,2..5] 
[0,4,8] 
ghci> map (`div` 2) [0,2..5] 
[0,1,2] 

लेकिन जब मैं आंशिक विभाजन का उपयोग मैं उत्पादन सूची में 4 तत्वों मिलती है:

ghci> map (/ 2) [0,2..5] 
[0.0,1.0,2.0,3.0] 
ghci> length (map (/ 2) [0,2..5]) 
4 

आप कृपया क्यों समझा सकते हैं map अधिक तत्व लौटा सकता है तो यह था?

धन्यवाद!

+1

संबंधित: http://stackoverflow.com/q/7290438/2541573 – Jubobs

+1

ध्यान दें कि 'लंबाई (मानचित्र एफ xs) == लंबाई (नक्शा एफ' xs ') 'प्रत्येक' लंबाई xs == लंबाई xs'' के लिए । यह * टाइप * के कार्यान्वयन पर स्वतंत्र रूप से सच होना चाहिए क्योंकि यह इसके प्रकार से निकला है। 'नक्शा' विभिन्न प्रकारों के बीच अंतर करने में सक्षम नहीं है और इसलिए निर्णय लिया कि कितने तत्व लौट सकते हैं। – Bakuriu

उत्तर

11

यह Float और Double के लिए Enum के कार्यान्वयन की वजह से है:

> [0,2..5] :: [Float] 
[0.0,2.0,4.0,6.0] 

यह कर नहीं map है, लेकिन Float। विशेष रूप से, यदि आप enumFromThenTo 0 2 5 :: [Float] पर कॉल करते हैं, तो आपको वही सूची मिल जाएगी। आप Double के लिए एक ही परिणाम देखेंगे।

यह the haskell report में संकेत दिया गया है, लेकिन व्यवहार निश्चित रूप से स्पष्ट नहीं है। मूलतः, यह (हम यहाँ कुछ हास्केल internals में हो रही है) numericEnumFromThenTo के कार्यान्वयन, जो Enum Float उदाहरण द्वारा प्रयोग किया जाता है करने के लिए नीचे आता है:

numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n') 
    where 
     p | n' >= n = (<= m + (n' - n)/2) 
      | otherwise = (>= m + (n' - n)/2) 

numericEnumFromThen n m = iterate (+ (m - n)) n 

numericEnumFromThen 0.0 2.0 तो आप सूची [0.0,2.0,4.0,6.0,8.0,...] पैदा करने हैं, तो आप takeWhile p करना उस पर, जो इस मामले में \x -> x <= 5.0 + (2.0 - 0.0)/2 फ़ंक्शन के बराबर है, या अधिक आसानी से \x -> x <= 6.0, यही कारण है कि 6.0[0.0,2.0..5.0] की आउटपुट सूची में शामिल है।

मैं व्याख्या नहीं कर सकते क्यों यह इस तरह से लागू हो जाता है, यह बहुत चौंकाने मेरे लिए बहुत है, लेकिन उम्मीद है कि मेरे द्वारा उत्तरित कैसे इसके कार्यान्वयन के लिए

+5

क्यों यह महत्वपूर्ण है कि '[0,0.1.1.1]' में हमेशा ग्यारह तत्व हों, जबकि इससे कोई फर्क नहीं पड़ता कि '[0,2.5.5]' कितने तत्व हैं क्योंकि यह पहले में बकवास है जगह। –

+2

@ रीडबर्टन पर विस्तृत करने के लिए, फ़्लोटिंग पॉइंट रेंजों के कार्यान्वयन को डिज़ाइन किया गया है ताकि सामान्य मामले में त्रुटियों को गोल करने के लिए लंबाई असंवेदनशील हो जब प्रारंभ और अंत बिंदु के बीच का अंतर * लगभग * चरणों की पूरी संख्या है। कटऑफ को इसके विपरीत "विपरीत" मामले में रखा जाता है जहां आधा कदम अतिरिक्त होता है। –

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

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