2016-09-11 13 views
12

मैं कुछ हास्केल स्रोत कोड देख रहा था और !_ साथ एक पैटर्न मैच में आए, कोड यहाँ है: http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.List.html#unsafeTakeहास्केल में "सख्त वाइल्डकार्ड" का उपयोग करना उपयोगी क्यों है, और यह क्या करता है?

take n xs | 0 < n  = unsafeTake n xs 
      | otherwise = [] 

-- A version of take that takes the whole list if it's given an argument less 
-- than 1. 
{-# NOINLINE [1] unsafeTake #-} 
unsafeTake :: Int -> [a] -> [a] 
unsafeTake !_ []  = [] 
unsafeTake 1 (x: _) = [x] 
unsafeTake m (x:xs) = x : unsafeTake (m - 1) xs 

मैं सच में समझ में नहीं आता कि कैसे "सख्त वाइल्डकार्ड" काम करता है और यही कारण है कि इसके लिए उपयोगी है यह फ़ंक्शन (या कोई अन्य फ़ंक्शन)।

उत्तर

12

विचार है कि unsafeTake (और उस बात के लिए take), जब खाली सूची के पहले m तत्वों लौटाने को कहा, यह खाली सूची वापस आ जाएगी, कोई बात नहीं क्या m का मूल्य है। लेकिन क्या होगा यदि m एक अभिव्यक्ति है जो अपवाद फेंकता है? उदाहरण के लिए, [] लौटने के लिए यह अजीब होगा। इसलिए हमें यह सुनिश्चित करने की ज़रूरत है कि m पूर्णांक का मूल्यांकन करता है भले ही हमें परवाह न हो कि उसका सटीक मूल्य क्या है (पाठ्यक्रम की खाली सूची केस के लिए)। इससे unsafeTake उसी तरीके से व्यवहार करता है जब इसकी पहली तर्क की बात आती है, इससे कोई फर्क नहीं पड़ता कि दूसरा तर्क (सूची) खाली है या नहीं।

+1

मुझे लगता है कि यदि आप 'अप' परिभाषित 'के साथ' टेक 'फ़ंक्शन का उपयोग' n' तर्क के रूप में करते हैं तो यह उल्लेखनीय है कि 'unsafeTake' फ़ंक्शन में त्रुटि पकड़ने की संभावना नहीं है क्योंकि' n' की तुलना पहले शून्य से की जाती है, यानी यह होगा पहले मूल्यांकन किया जाना चाहिए। लेकिन क्योंकि 'टेक' फ़ंक्शन जितना संभव हो उतना रेखांकित किया जाना चाहिए (जैसा कि टिप्पणी कहता है) तो कुछ ऑप्टिमाइज़ेशन के बाद यह चेक गायब हो सकती है। यही कारण है कि हमें 'असुरक्षित' में भी '! _' की आवश्यकता है। – Shersh

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