Pracuję poprzez Learn You a Haskell, a ja zajmuję się sekcją o monoidach. W tej części autor definiuje metodę foldMap na drzewie, co następuje:Skąd pochodzą składanie/składanie implementacji składanego dla drzew binarnych w haskell?
instance F.Foldable Tree where
foldMap f Empty = mempty
foldMap f (Node x l r) = F.foldMap f l `mappend`
f x `mappend`
F.foldMap f r
który działa dobrze i jest całkowicie Baller. Jednak on stwierdza: "Teraz, gdy mamy już składaną instancję dla naszego typu drzewa, otrzymamy foldr i foldl za darmo!" i pokazuje następujący kod:
testTree = Node 5
(Node 3
(Node 1 Empty Empty)
(Node 6 Empty Empty)
)
(Node 9
(Node 8 Empty Empty)
(Node 10 Empty Empty)
)
ghci> F.foldl (+) 0 testTree
42
ghci> F.foldl (*) 1 testTree
64800
Teraz jestem zdezorientowany. Nigdzie nie było implementacji foldl lub foldr napisanych dla drzew. Wydaje się, że funkcje działają podobnie do mapy foldmap, ale umieszczają początkowy akumulator jako głowę drzewa, a następnie foldMapping na odpowiednim monoidzie, ale tak naprawdę nie może działać tak, ponieważ foldl i foldr mają bardziej ogólne funkcje niż monoidy "+" i "*" jako argumenty. Gdzie faktycznie są zaimplementowane foldl i foldr, jak działają i dlaczego definiowanie foldMap powoduje ich istnienie?
Czy spojrzałeś na kod źródłowy do Data.Foldable? Definicje w klasie Foldable powinny być wystarczająco informacyjne, aby odpowiedzieć na twoje pytanie. –
TypKlasy Haskell mogą mieć domyślne implementacje niektórych metod pod względem innych. W tym przypominają, jak mixiny działają w innych językach. Na przykład w Ruby wystarczy zdefiniować <=>, aby uzyskać dostęp do pozostałych metod Porównywalnych. – danidiaz
możliwy duplikat [Foldr/Foldl za darmo, gdy drzewo implementuje składaną mapę folderów?] (Http://stackoverflow.com/questions/23319683/foldr-foldl-for-free-when-tree-is-implementing-foldable-foldmap) –