2017-01-07 48 views
5

Traversable, bir yapısı yapısını çözmeden değiştirilebilen elemanların (bir listeye karşılık gelebilecek) bir “yolu” olan konteynır sınıfıdır. Bu nedenle, bu liste-durum geçişi biraz hacklenmiş ve muhtemelen bunu yapmanın en etkili yolu değil gibi görünmektedir. Yukarıdaki ya da daha genel bir görevi yerine getiren standart bir işlev olacağını varsayalım, ama ne olacağını anlayamıyorum.Bir listede geçiş yapabileceğiniz en standart/genel yol nedir?

cevap

5

mapAccumL/mapAccumR nedir? verimlilik sorusu üzerine

tzipWith :: Traversable t => (a -> b -> c) -> [a] -> t b -> Maybe (t c) 
tzipWith f xs = sequenceA . snd . mapAccumL pair xs 
    where pair [] y = ([], Nothing) 
      pair (x:xs) y = (xs, Just (f x y)) 

tzip :: Traversable t => [a] -> t b -> Maybe (t (a, b)) 
tzip = tzipWith (,) 

ghci> tzip [1..] [4,5,6] 
Just [(1,4),(2,5),(3,6)] 

ghci> tzip [1,2] [4,5,6] 
Nothing 

- under the hood mapAccum fonksiyonları yüzden gerçekten yaptığım tüm yüksek dereceden fonksiyonunda kodunuzun zorunlu kısmını ele olduğunu, devlet monad kullanın. Bu kodun sizinkinden daha iyi performans göstermesini beklemiyordum. Ama ben sadece Traversable t verilen State monad (veya ST), daha iyi yapabileceğinizi düşünmüyorum.

+0

@WillNess Nah, yalnızca geçiş işlemini bitirdikten sonra giriş listesinde kalan herhangi bir şey olup olmadığını kontrol etmeniz yeterlidir. Kodumu güncelleyeceğim –

+0

@WillNess Sorgulayıcı, listede 'Traversable' öğesini doldurmak için yeterli öğe yoksa 'Hiçbir şey' geri dönmek istediğini düşünüyorum. Fikir, –

+0

ah değerlerinin her birini eşleştirirken 'Traversable' şeklini tutmaktır, bu mantıklıdır. Bu, önceki sürümün gerçekten doğru olduğu anlamına gelir. :) Önceki sürümünüzü geri yükledim ve açıklayıcı bir örnek ekledim. Bunun için üzgünüm. –