2010-04-13 13 views
13

हास्केल में, एक कार्य "ले एन एन सूची" है जो सूची से पहले एन तत्व लौटाता है। उदाहरण के लिए "योग (3 xs ले लो)" सूची xs में पहले तीन तत्वों को बताता है। क्या एफ # बराबर है? मुझे उम्मीद है कि यह सूची-कार्यों में से एक होगा, लेकिन मैं मिलान करने वाले किसी भी चीज़ को नहीं खोज सकता।क्या एफ # के पास हैस्केल के बराबर है?

उत्तर

15

हाँ, इसे Seq.take कहा जाता है। उपयोग हास्केल के समान प्रतीत होता है: Seq.takeगिनती स्रोत किसी सूची पर इसका उपयोग करने के लिए, पहले List.toSeq का उपयोग करें। (अद्यतन: जाहिरा तौर पर टिप्पणी से, यह आवश्यक है।)

+0

ऐसा लगता है कि मैं वास्तव में क्या देख रहा हूं। अब परीक्षण :) – McMuttons

+13

दरअसल, हैकेल का कार्य Seq.truncate जैसा कार्य करता है, Seq.take नहीं। – sepp2k

+2

चूंकि सूची IENumerable से विरासत में प्राप्त होती है, इसलिए मुझे इसे पहले से अनुक्रम में परिवर्तित करने की आवश्यकता नहीं है। एक सूची में Seq.take का उपयोग ठीक काम किया। – McMuttons

39

कुछ चीजें, Seq.take और Seq.truncate (के रूप में @ sepp2k द्वारा बताया) के बीच का अंतर स्पष्ट करने के लिए है कि एक दूसरे के आप एक दृश्य दे देंगे जो आपके द्वारा निर्दिष्ट तत्वों की संख्या पर लौटाता है (लेकिन अगर अनुक्रम की लंबाई कम है, तो यह आपको कम तत्व देगा)।

अनुक्रम उत्पन्न करता है, तो आप मूल सूची की लंबाई से परे एक तत्व तक पहुँचने का प्रयास Seq.take समारोह एक अपवाद फेंक देते हैं (ध्यान दें कि Seq.take समारोह क्योंकि परिणाम lazily अनुक्रम उत्पन्न होता है अपवाद तुरंत फेंक नहीं है)।

इसके अलावा, आपको सूची को अनुक्रम में रूपांतरित करने की आवश्यकता नहीं है। कवर के तहत, list<'a> एक .NET क्लास है जो seq<'a> प्रकार से प्राप्त होता है, जो एक इंटरफ़ेस है। seq<'a> टाइप IEnumerable<'a> के लिए वास्तव में केवल एक प्रकार का उपनाम है, इसलिए इसे अन्य सभी संग्रहों (एरे, म्यूटेबल सूचियां इत्यादि सहित) द्वारा कार्यान्वित किया जाता है। निम्नलिखित कोड ठीक काम करेगा:

let list = [ 1 .. 10 ] 
let res = list |> Seq.take 5 

हालांकि, अगर आप प्रकार का एक परिणाम प्राप्त करने के लिए list<int> आप अनुक्रम एक सूची वापस करने के लिए कन्वर्ट करने के लिए (क्योंकि एक सूची एक दृश्य की तुलना में अधिक विशिष्ट प्रकार है) की आवश्यकता होगी चाहते हैं:

let resList = res |> List.ofSeq 

मुझे यकीन है कि क्यों एफ # पुस्तकालयों List.take या List.truncate प्रदान नहीं करते हैं नहीं कर रहा हूँ। मुझे लगता है कि लक्ष्य संग्रह में से सभी प्रकार के लिए कार्यों के पूरे सेट reimplementing से बचने के लिए था, इसलिए उन जहां दृश्यों के लिए कार्यान्वयन काफी अच्छा है जब एक अधिक विशिष्ट संग्रह प्रकार के साथ काम केवल Seq मॉड्यूल में उपलब्ध हैं (लेकिन यह केवल मेरा अनुमान है ...)

+0

अच्छा स्पष्टीकरण। – McMuttons

+0

@McMuttons: धन्यवाद! मुझे यकीन नहीं था कि मुझे इसे पोस्ट करना चाहिए या नहीं, क्योंकि ज्यादातर चीजें पहले से ही टिप्पणियों में उल्लिखित थीं .. इसलिए, मुझे खुशी है कि यह उपयोग किया जाता है! –

1

Seq.take काम करता है, के रूप में दूसरों को पहले से ही कहा है, लेकिन एक सूची पर सभी Seq संचालन लागत से आते हैं। Seq.take के मामले में, यह, आश्चर्य की बात नहीं है के रूप में सूची कॉपी किया गया है।

यह अधिक उल्लेखनीय है कि, उदाहरण के लिए, सूची में Seq.concat सूची.concat से बहुत अधिक समय लेता है। मुझे लगता है कि संकेत मिलता है कि आप सिर्फ एक seq के रूप में सूची तक पहुँच नहीं है जब आप एक Seq.xxx फ़ंक्शन को कॉल लगता है, लेकिन यह है कि पर्दे के पीछे एक Seq में कॉपी किया/रूपांतरित में सूची के रूप में अच्छी तरह से।

संपादित करें:

#time "on";; 
let lists = [for i in 0..5000000 -> [i..i+1]];; 
Seq.length (Seq.concat lists);; 
List.length (List.concat lists);; 

मेरी मशीन पर, List.length संस्करण, के बारे में 1.9 सेकेंड लेता है जबकि Seq.length संस्करण के बारे में लेता है: कारण मैं ऊपर निष्कर्ष आकर्षित किया है, इस बेंच एफ # इंटरैक्टिव का उपयोग कर रहा था 3।8 सेकंड (सूची पीढ़ी लाइन को छोड़कर, केवल लंबाई रेखाओं के कुछ बार-बार परीक्षणों का सबसे छोटा समय)।

+3

मुझे नहीं लगता कि यह सही है। '<'t> '' seq <'t>' इंटरफ़ेस लागू करता है इसलिए कोई रूपांतरण आवश्यक नहीं है, न ही प्रतिलिपि बनाने की अपेक्षा करने का कोई कारण है। साथ ही, 'Seq.take' आलसी काम करता है, जबकि' List.take' नहीं हो सकता है, इसलिए एक लंबी सूची पर, अनुक्रम संचालन लगभग निश्चित रूप से तेज हो जाएगा यदि परिणामस्वरूप अनुक्रम के सामने केवल आवश्यकता हो। हालांकि, यह सच हो सकता है कि पैटर्न मिलान के माध्यम से 'List.take' फ़ंक्शन को कार्यान्वित करना' Seq.take' कार्यान्वयन से बेहतर प्रदर्शन करेगा जो सूची को दर्शाता है यदि आप परिणामस्वरूप सूची के सभी तत्वों को बेसब्री से एक्सेस करना चाहते हैं। – kvb

+1

रूपांतरणों के बारे में मेरा निष्कर्ष शायद गलत था, लेकिन कुछ चल रहा है और इसमें अतिरिक्त समय लगता है। मैंने अपनी पोस्ट संपादित की और कुछ समय जोड़ा। – Batibix

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