में आंशिक गणना का अनुकूलन मैं उत्सुक कैसे इस कोड का अनुकूलन करने के हूँ:हास्केल
fun n = (sum l, f $ f0 l, g $ g0 l)
where l = map h [1..n]
यह मानते हुए कि f
, f0
, g
, g0
, और h
सभी महंगे होते हैं, लेकिन निर्माण और l
के भंडारण अत्यंत है महंगा।
लिखित के रूप में, l
तब तक संग्रहीत किया जाता है जब तक लौटा हुआ ट्यूपल पूरी तरह से मूल्यांकन नहीं किया जाता है या कचरा एकत्र नहीं किया जाता है। इसके बजाए, length l
, f0 l
, और g0 l
सभी को निष्पादित किया जाना चाहिए जब भी उनमें से कोई भी निष्पादित हो, लेकिन f
और g
में देरी होनी चाहिए।
यह इस व्यवहार लेखन द्वारा निर्धारित किया जा सकता है प्रकट होता है:
fun n = a `seq` b `seq` c `seq` (a, f b, g c)
where
l = map h [1..n]
a = sum l
b = inline f0 $ l
c = inline g0 $ l
या बहुत समान:
fun n = (a,b,c) `deepSeq` (a, f b, g c)
where ...
हम शायद रूप में अच्छी तरह से एक ही प्रभाव को प्राप्त करने के लिए आंतरिक प्रकार का एक समूह निर्दिष्ट कर सकते हैं, जो दर्दनाक लग रहा है। क्या कोई अन्य विकल्प भी हैं?
इसके अलावा, मैं स्पष्ट रूप से मेरे inline
कि संकलक sum
, f0
, और g0
फ़्यूज़ एकल लूप कि निर्माण करती है और अवधि द्वारा l
अवधि की खपत में साथ उम्मीद कर रहा हूँ। मैं मैन्युअल इनलाइनिंग के माध्यम से यह स्पष्ट कर सकता हूं, लेकिन वह चूसना होगा। क्या कभी भी बनाए जाने और/या इनलाइनिंग को मजबूर करने से सूची l
सूची को स्पष्ट रूप से रोकने के तरीके हैं? अगर संकलन के दौरान इनलाइनिंग या संलयन विफल हो तो चेतावनियां या त्रुटियां उत्पन्न होती हैं?
एक अलग रूप में के रूप में, मैं क्यों seq
, inline
, lazy
, आदि सभी प्रस्तावना में let x = x in x
द्वारा करने के लिए परिभाषित कर रहे हैं के बारे में उत्सुक हूँ। क्या यह बस उन्हें कंपाइलर को ओवरराइड करने की परिभाषा देने के लिए है?
अंतिम प्रश्न के जवाब में: http://stackoverflow.com/a/8654407/1011995 –
'f0' और 'g0' पूरी तरह से मनमानी हैं, या वे' फ़ोल्डर 'के संदर्भ में लिखे जा सकते हैं? – dave4420
एक (ए, बी, सी) -एक्यूमुलेटर के साथ एक साधारण गुना नहीं होगा? – Sarah