module Data.NonEmpty.Foldable where

import qualified Data.Foldable as Fold
import Data.Foldable (Foldable, )


{- |
It holds:

> foldMap f . Mapped g = foldMap f . fmap g

but use of 'Mapped' avoids 'Functor' constraint.
-}
data Mapped f a b = Mapped (a -> b) (f a)


instance (Foldable f) => Foldable (Mapped f a) where
   foldMap :: (a -> m) -> Mapped f a a -> m
foldMap a -> m
g (Mapped a -> a
f f a
xs) = (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
Fold.foldMap (a -> m
g (a -> m) -> (a -> a) -> a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f) f a
xs
   foldr :: (a -> b -> b) -> b -> Mapped f a a -> b
foldr a -> b -> b
g b
x (Mapped a -> a
f f a
xs) = (a -> b -> b) -> b -> f a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Fold.foldr (a -> b -> b
g (a -> b -> b) -> (a -> a) -> a -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f) b
x f a
xs
   foldl :: (b -> a -> b) -> b -> Mapped f a a -> b
foldl b -> a -> b
g b
x (Mapped a -> a
f f a
xs) = (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Fold.foldl (\b
acc -> b -> a -> b
g b
acc (a -> b) -> (a -> a) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f) b
x f a
xs