2012-02-11 12 views
9

bir örnek sağlar? foldr yalnızca üç bağımsız değişken alır - ancak burada dört geçirilir: step, id, xs, z. (Toplamı birini bekler çünkü)İşlev, üç yerine dört argüman alıyor - neden bu ara vermiyor?</p> <pre><code>myFoldl f z xs = foldr step id xs z where step x g a = g (f a x) </code></pre> <p>Sorum şu: Neden bu kod derliyor sayfa 95 yazar "Gerçek Dünya Haskell", Okuma

Örneğin, bu işe yaramazsa:

sum filter odd [1,2,3] 

yerine ben yazmak gerekir:

sum $ filter odd [1,2,3] 

cevap

12

(örneğin) İşte foldr türüdür için uzmanlaşmış? Hadi bir deneyelim! Bizi veren a -> a -> aa -> (a -> a) aynıdır, Haskell

(a -> (d -> d) -> (d -> d)) -> (d -> d) -> [a] -> (d -> d) 
  • :

    1. ikinci parametrenin (b) olarak o id :: d -> d vererek, bu yüzden türü içine o yerine izin mi (parantez son seti kaldırma):

      (a -> (d -> d) -> (d -> d)) -> (d -> d) -> [a] -> d -> d 
      
    2. en basitleştirmek izinikame edilmesi suretiyle(d -> d için (a -> (d -> d) -> (d -> d)) ve f) için, daha kolay okunmasını sağlamak için:

      e -> f -> [a] -> d -> d 
      

    yüzden açıkça biz dört argüman fonksiyonunu inşa ettik görebilirsiniz! Başım ağrıyor.


    Burada bir n-arg fonksiyon arasında bir n + 1-argüman fonksiyonunu oluşturmak basit bir örnek verilmiştir:

    Prelude> :t id 
    id :: a -> a 
    

    id bir bağımsız değişken bir fonksiyonudur.

    Prelude> id id id id id 5 
    5 
    

    Ama ben sadece 5 args verdim!

  • +0

    Neden "id id 5" yapabileceğinizi anlamıyorum ama yapamazsınız: foo x = x + 1; bar y = y + 1; foo çubuğu 1'? – drozzy

    +4

    @drozzy - her şey tip ve polimorfizm ile ilgili. 'Id :: a -> a' seçeneğini seçin: * a için herhangi bir * tipini kullanabilirsiniz. Ancak, foo 'farklıdır, çünkü kısıtları vardır: bir sayıya ihtiyaç duyar: foo :: (Num a) => a -> a'. bar :: (Num a) => a -> a ',' Num' tipinin bir örneği değildir ve bu nedenle '(Num a)' foo'nun kısıtlamasını karşılamaz. –

    +2

    @drozzy Belki de fonksiyon uygulamasının çağrışımını açıklığa kavuşturursak yardımcı oluruz! Unutmayın ki, id id '5' (id id) 5' olarak - yani, 'id' ilk önce 'id' argümanı olarak, sonra '5' sonuca bir argüman olarak - ' id (id 5). –

    10

    Çünkü foldr ne kadar polimorfik ait açıklanmıştır:

    foldr :: (a -> b -> b) -> b -> [a] -> b 
    

    Burada, bir işlev türüne b örneğini çektik.

    Prelude> :t foldr 
    foldr :: (a -> b -> b) -> b -> [a] -> b 
    

    biz dört argüman fonksiyonu haline anlamaya Can:, böylece foldr tipi

    foldr :: (a -> (c -> c) -> (c -> c)) -> (c -> c) -> [a] -> c -> c 
    
    +1

    Ayrıca orijinal sorudaki nötr öğenin zaten bir işlev olduğunu, id kimliğine de dikkat çekebilirsiniz. – ShiDoiSi

    9

    foldr sadece 3 argümanları

    Yanlış

    sürer. Haskell'deki tüm işlevler tam olarak 1 argüman alır ve tam olarak 1 sonuç üretir.

    foldr :: (a -> b -> b) -> b -> [a] -> b 
    

    See, foldr bir argüman (a -> b -> b) alır ve 1 sonuç üretir: b -> [a] -> b. Bunu gördüğünüzde:

    foldr step id xs z 
    

    Unutmayın, bunun için sadece kısaltmasıdır: Bu saçmalıktır neden

    ((((foldr step) id) xs) z) 
    

    açıklıyor:

    sum filter odd [1,2,3] 
    (((sum filter) odd) [1,2,3]) 
    

    sum :: Num a => [a] -> a onun girdi olarak bir liste alır ama sen bir fonksiyon verdin.

    İlgili konular