यह व्यापक रूप से ज्ञात नहीं है, लेकिन वास्तव में अपने 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 में दिया गया है।
फ़ोल्डल के दो संस्करणों के लिए स्रोत कोड की तुलना करें, और आपको प्रबुद्ध हो सकता है। – augustss
@augustss शायद, क्या आप इसका उत्तर दे सकते हैं? – jackalope
जैसा कि आप देख सकते हैं, फ़ोल्डल कॉल से पहले पहले तर्क को लेगो की गणना करता है, जबकि फ़ोल्डल (सामान्य रूप से) एक थंक पास करेगा जो आवश्यक होने पर मूल्यांकन किया जाएगा। – augustss