2015-08-08 16 views
7

Yeni Haskell programcısında nasıl çalıştığını açıklayın, foldr'un nasıl uygulandığını görmek için kaynaklara yeterince gidin. Eh, kod basit (yeni gelenler hakkında OldList veya FTP hakkında bilmek beklemeyin).Yeni katmanın Haskell

Yeni kod nasıl çalışıyor?

-- | 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

değil yinelenen ama [I den 'foldr' alma konusunda bir cevap yazdım' foldMap' bir süre önce] (http://stackoverflow.com/a/23319967/2751851). Cevap, 'Monoid' ile temel aşinalılığı varsayar, bu yüzden lütfen bize verilen çok şey alınıp alınmadığını söyleyin. – duplode

cevap

10

Sadece değilthe answer @duplode linked olan parçaların söz edeceğiz.

İlk olarak, listelediğiniz uygulamalar varsayılan yöntemleridir. Her Foldable tip bunlardan en az bir kendi özgül versiyonunu sunmak gerekiyor ve her zaman olduğu gibi listeleri ([]) foldr, which is implemented hemen hemen sağlar:

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

(Hangisi verimlilik için, Haskell raporu sürümünden farklı biraz.)

Ayrıca duplode cevabı beri Foldable varsayılan ufak bir değişiklik garip #. operatör, ghc en Data.Foldable kodunda dahili olarak kullanılan olmasıdır. Temel olarak 'un çalışmasını sağlayan daha verimli bir sürümü, sol işlev yeni tip bir sarmalayıcı/istemcisi işleviyse yalnızca çalışır. Yeni newtype zorlama mekanizması kullanılarak tanımlanır, ve esasen hiçliğe optimize alır: Muhtemelen

(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c) 
(#.) _f = coerce 
{-# INLINE (#.) #-}