Trong LYAH, có một đoạn mã trông giống như thế này.Cách Foldable.foldl hoạt động trên Num a => a
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
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
ghci> F.foldl (+) 0 testTree
42
ghci> F.foldl (*) 1 testTree
64800
Theo như tôi biết, foldMap
là loại foldMap :: (Monoid m, Foldable t) => (a -> m) -> t a -> m
, nhưng Num a => a
bản thân không phải là loại Monoid
, vì vậy tôi tự hỏi làm thế nào để Foldable.foldl
thực sự làm việc ở đây? Và kể từ foldMap
được gọi nội bộ theo số Foldable.foldl
, loại số Monoid
là gì?
Xin chào @WillemVanOnsem, cảm ơn sự giúp đỡ của bạn. Đó là chính xác những gì tôi đang bối rối về, bạn đã đề cập 'mempty = 1', sau đó là loại của' mempty' ở đây? Tôi không thể hiểu được điều này bởi vì không giống như 'Sum' và' Product', 'Int' không phải là typeclass' Monoid' AFAIK. Bạn có thể giải thích thêm một chút về điều này? cảm ơn –
Hmm, tôi hiểu, tôi mới làm quen với Haskell, tôi đoán đó là phần tôi đang thiếu. Cảm ơn rất nhiều :) –
Lưu ý rằng thủ thuật endo này khá tiên tiến, chắc chắn không phải là tài liệu mới bắt đầu. Có lẽ sẽ dễ dàng hơn khi viết một thực thi 'foldl' đầu tiên chuyển đổi bất kỳ có thể gập lại thành một danh sách đơn giản, sử dụng' foldMap (\ x -> [x]) 'để monoid đơn giản là' [a] ', và sau đó thực hiện' foldl' trên danh sách. Nó kém hiệu quả hơn, nhưng có lẽ dễ hiểu hơn. Nó có thể làm cho một bài tập tốt :) – chi