संक्षेप में, जितनी बार आप सोचेंगे उतनी बार नहीं। इसका कारण यह है कि पुस्तकालयों को कार्यान्वित करते समय स्ट्रीम फ्यूजन जैसी "फैंसी तकनीकें" नियोजित की जाती हैं, और लाइब्रेरी उपयोगकर्ताओं को उनके बारे में चिंता करने की आवश्यकता नहीं होती है।
Data.List.map
पर विचार करें। आधार पैकेज के रूप में
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
यह map
आत्म पुनरावर्ती है map
को परिभाषित करता है, तो GHC यह इनलाइन नहीं होंगे।
हालांकि, base
भी निम्न पुनर्लेखन नियमों को परिभाषित करता है:
{-# RULES
"map" [~1] forall f xs. map f xs = build (\c n -> foldr (mapFB c f) n xs)
"mapList" [1] forall f. foldr (mapFB (:) f) [] = map f
"mapFB" forall c f g. mapFB (mapFB c f) g = mapFB c (f.g)
#-}
इस के माध्यम से foldr/build fusion, तो, समारोह इनकार नहीं किया जा सकता है, यह मूल map
साथ बदलता है map
का उपयोग करता है बदल देता है। चूंकि संलयन स्वचालित रूप से होता है, यह उपयोगकर्ता के बारे में जागरूक होने पर निर्भर नहीं करता है।
सबूत के रूप में यह सब काम करता है, आप जांच सकते हैं कि जीएचसी विशिष्ट इनपुट के लिए क्या उत्पादन करता है।
proc1 = sum . take 10 . map (+1) . map (*2)
eval1 = proc1 [1..5]
eval2 = proc1 [1..]
जब -O2 साथ संकलित, GHC proc1
के सभी एक ही पुनरावर्ती रूप में (के रूप में -ddump-simpl
के साथ मुख्य उत्पादन में देखा) फ़्यूज़: इस कार्य के लिए।
बेशक इन तकनीकों को पूरा करने के लिए सीमाएं हैं।उदाहरण के लिए, बेवकूफ औसत कार्य, mean xs = sum xs/length xs
आसानी से मैन्युअल रूप से एक गुना में परिवर्तित हो जाता है, और frameworks exist that can do so automatically, हालांकि वर्तमान में मानक कार्यों और संलयन ढांचे के बीच स्वचालित रूप से अनुवाद करने का कोई ज्ञात तरीका नहीं है। तो इस मामले में, उपयोगकर्ता को कंपाइलर-उत्पादित कोड की सीमाओं से अवगत होना चाहिए।
तो कई मामलों में संकलक तेजी से और सुरुचिपूर्ण कोड बनाने के लिए पर्याप्त रूप से उन्नत होते हैं। यह जानकर कि वे ऐसा कब करेंगे, और जब संकलक गिरने की संभावना है, तो आईएमएचओ कुशल हास्केल कोड लिखने के तरीके सीखने का एक बड़ा हिस्सा है।
मैंने आपके लिए लिंक में संपादित किया है और ऊपर उठाया है। बहुत बढ़िया जवाब! – ehird
आह, अद्भुत, यह एक बहुत स्पष्ट तस्वीर पेंट करता है, धन्यवाद! –
क्या आपका मतलब 'जी (एक्स: एक्सएस) = 2 * एक्स: जी एक्सएस' था? – pat