2015-08-08 6 views
7

नया हास्केल प्रोग्रामर जल्द ही स्रोतों पर जायेगा यह देखने के लिए कि foldr लागू किया गया है। खैर, कोड सरल होता था (नए आने वालों को OldList या FTP के बारे में जानने की उम्मीद न करें)।बताएं कि नया फ़ोल्डर कैसे काम करता है हास्केल

नया कोड कैसे काम करता है?

-- | Map each element of the structure to a monoid, 
-- and combine the results. 
foldMap :: Monoid m => (a -> m) -> t a -> m 
foldMap f = foldr (mappend . f) mempty 

-- | Right-associative fold of a structure. 
-- 
-- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@ 
foldr :: (a -> b -> b) -> b -> t a -> b 
foldr f z t = appEndo (foldMap (Endo #. f) t) z 
+0

शायद नहीं एक नकली है, लेकिन [मैं 'foldr' से हो रही पर एक जवाब लिखा' foldMap' थोड़ी देर पहले] (http://stackoverflow.com/a/23319967/2751851)। उत्तर 'मोनॉयड' के साथ मूल परिचितता मानता है, इसलिए कृपया हमें बताएं कि क्या यह बहुत सी चीजों को मंजूरी देता है। – duplode

उत्तर

10

मैं सिर्फ भागों कि नहींthe answer @duplode linked में हैं उल्लेख करेंगे।

सबसे पहले, आपके द्वारा सूचीबद्ध इन कार्यान्वयन डिफ़ॉल्ट विधियां हैं। हर Foldable प्रकार कम से कम एक उनमें से के अपने स्वयं के विशेष संस्करण प्रदान करने की जरूरत है, और सूची ([]) foldr, which is implemented काफी प्रदान के रूप में यह हमेशा किया गया है:

foldr k z = go 
      where 
      go []  = z 
      go (y:ys) = y `k` go ys 

(है कौन, दक्षता के लिए, थोड़ा हास्केल रिपोर्ट संस्करण से अलग।)

इसके अलावा, Foldable डिफ़ॉल्ट duplode के जवाब के बाद से में एक मामूली बदलाव है कि अजीब #. ऑपरेटर, GHC के Data.Foldable कोड में आंतरिक रूप से उपयोग है। यह मूल रूप से . का एक अधिक कुशल संस्करण है जो केवल काम करता है जब बायां फ़ंक्शन एक नया प्रकार का रैपर/अनैपर फ़ंक्शन होता है। यह नया newtype बलात्कार प्रणाली का उपयोग करके निर्धारित किया है, और अनिवार्य रूप कुछ भी नहीं में अनुकूलित हो जाता है:

(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) 
(#.) _f = coerce 
{-# INLINE (#.) #-} 
संबंधित मुद्दे