折叠结构反向
在 Dual
monoid 的帮助下, 任何折叠都可以在相反的方向上运行,这会翻转现有的幺半群,以便聚合反向。
newtype Dual a = Dual { getDual::a }
instance Monoid m => Monoid (Dual m) where
mempty = Dual mempty
(Dual x) `mappend` (Dual y) = Dual (y `mappend` x)
当用 Dual
翻转 foldMap
调用的底层 monoid 时,折叠向后运行; 下面 Reverse
类型是在限定 Data.Functor.Reverse
:
newtype Reverse t a = Reverse { getReverse::t a }
instance Foldable t => Foldable (Reverse t) where
foldMap f = getDual . foldMap (Dual . f) . getReverse
我们可以使用这个机器为列表写一个简洁的 reverse
:
reverse :: [a] -> [a]
reverse = toList . Reverse