2013-01-11 30 views
5

< का पालन करें असली दुनिया हास्केल >, यह कहा जाता foldl'foldl की सख्त संस्करण हैं।हैकेल में सख्त संस्करण का क्या अर्थ है?

लेकिन यह कठिन मुझे समझने के लिए है, strict क्या मतलब है ??

foldl f z0 xs0 = lgo z0 xs0 
     where 
      lgo z []  = z 
      lgo z (x:xs) = lgo (f z x) xs 


foldl' f z0 xs0 = lgo z0 xs0 
    where lgo z []  = z 
      lgo z (x:xs) = let z' = f z x in z' `seq` lgo z' xs 
+2

फ़ोल्डल के दो संस्करणों के लिए स्रोत कोड की तुलना करें, और आपको प्रबुद्ध हो सकता है। – augustss

+0

@augustss शायद, क्या आप इसका उत्तर दे सकते हैं? – jackalope

+0

जैसा कि आप देख सकते हैं, फ़ोल्डल कॉल से पहले पहले तर्क को लेगो की गणना करता है, जबकि फ़ोल्डल (सामान्य रूप से) एक थंक पास करेगा जो आवश्यक होने पर मूल्यांकन किया जाएगा। – augustss

उत्तर

6

foldl और (सख्त) foldl 'शब्दार्थ बराबर के करीब हैं। अंतर प्रदर्शन में है, खासकर जब आप एक बड़ी सूची में स्थानांतरित कर रहे हैं। आलस्य के पास एक थंक और फोल्ड बनाने का एक ऊपरी भाग है, जो उस परिणाम पर पहुंचने का अधिक प्रभावी तरीका है क्योंकि यह एक बड़ा हिस्सा नहीं बनाता है।

एक बहुत अच्छी लेख में विस्तार से Haskell Wiki

सख्त कार्यों पर इस समझा नहीं है अन्य भाषाओं सी में कार्य या में है कि उनके तर्क आम तौर पर उत्सुकता से मूल्यांकन किया जाता है की तरह काम करता है।

0

एक सख्त कार्य एक ऐसा कार्य है जिसका तर्क शरीर से पहले मूल्यांकन किया जाता है।

+0

अभी भी समझना मुश्किल है ... – jackalope

+1

नहीं, यह कोई फ़ंक्शन नहीं है जिसका तर्क कॉल से पहले मूल्यांकन किया जाता है। एक सख्त कार्य, अनौपचारिक रूप से, एक कार्य है जो इसके तर्कों का मूल्यांकन करता है। – augustss

+0

@augustss: * बिना शर्त (दाएं?) –

12

यह व्यापक रूप से ज्ञात नहीं है, लेकिन वास्तव में अपने foldl' संचायक बहस में गैर सख्त है! प्रकार याद:

foldl' :: (a -> b -> a) -> a -> [b] -> a 

तर्क 2 में इसका कड़ाई, समारोह की कठोरता तर्क 1 के लिए दिए गए पर निर्भर करता है के रूप में आप अगर आप const पारित देखें:

Prelude Data.List> foldl' (const (+1)) undefined [1] 
2 
Prelude Data.List> foldl' (const (+1)) undefined [1..4] 
5 

आप सोचा, भोलेपन से होता है, कि "फ़ोल्डल" सख्त "मतलब" संचयक तर्क में सख्त है "। उपरोक्त विरोधाभास है कि।

हालांकि, यह और भी अधिक घातक है, के रूप में कड़ाई केवल पाश की विपक्ष मामले में समारोह आवेदन के परिणाम पर है। तो आप अभी भी नीचे मिल अगर आप आधार मामला दर्ज करते हैं, लेकिन नहीं आगमनात्मक मामला:

Prelude Data.List> foldl' (const (+1)) undefined [] 
*** Exception: Prelude.undefined 

तो कठोरता in argument 2भी तर्क 3 के मूल्य पर निर्भर करता है! "पूरी तरह से" अपने 2 तर्क में सख्त:

यह मैं इसे कैसे लिखना चाहते हैं।

foldl' f z0 xs0 = go z0 xs0 
    where 
    go !z []  = z 
    go !z (x:xs) = go (f z x) xs 

कौन सा दूसरा तर्क में सही मायने में सख्त है, जैसा कि आप देख सकते हैं:

Prelude Data.List.Stream> foldl' (\a b -> 1) undefined [undefined] 
*** Exception: Prelude.undefined 

Haskell2010 संस्करण के साथ तुलना में:

Prelude Data.List.Stream> Data.List.foldl' (\a b -> 1) undefined [undefined] 
1 

यह actuall एक व्यावहारिक प्रभाव पड़ता है - वर्तमान परिभाषा लगातार अपने संचयक तर्क को अनबॉक्स नहीं करेगी।

ऐतिहासिक नोट: यह पता चला था कि जब हम 2007 में स्ट्रीम फ़्यूज़न पेपर के लिए सूची लाइब्रेरी की सख्तता अर्थशास्त्र निर्दिष्ट कर रहे थे, और सख्तता निर्दिष्ट करने का दृष्टिकोण डंकन कॉउट के PhD thesis में दिया गया है।