module Data.Parameterized.TraversableF
( FunctorF(..)
, FoldableF(..)
, TraversableF(..)
, traverseF_
, fmapFDefault
, foldMapFDefault
, allF
, anyF
) where
import Control.Applicative
import Control.Monad.Identity
import Data.Coerce
import Data.Functor.Const
import Data.Monoid
import GHC.Exts (build)
class FunctorF m where
fmapF :: (forall x . f x -> g x) -> m f -> m g
instance FunctorF (Const x) where
fmapF _ = coerce
(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)
(#.) _f = coerce
class FoldableF (t :: (k -> *) -> *) where
foldMapF :: Monoid m => (forall s . e s -> m) -> t e -> m
foldMapF f = foldrF (mappend . f) mempty
foldrF :: (forall s . e s -> b -> b) -> b -> t e -> b
foldrF f z t = appEndo (foldMapF (Endo #. f) t) z
foldlF :: (forall s . b -> e s -> b) -> b -> t e -> b
foldlF f z t = appEndo (getDual (foldMapF (\e -> Dual (Endo (\r -> f r e))) t)) z
foldrF' :: (forall s . e s -> b -> b) -> b -> t e -> b
foldrF' f0 z0 xs = foldlF (f' f0) id xs z0
where f' f k x z = k $! f x z
foldlF' :: (forall s . b -> e s -> b) -> b -> t e -> b
foldlF' f0 z0 xs = foldrF (f' f0) id xs z0
where f' f x k z = k $! f z x
toListF :: (forall tp . f tp -> a) -> t f -> [a]
toListF f t = build (\c n -> foldrF (\e v -> c (f e) v) n t)
allF :: FoldableF t => (forall tp . f tp -> Bool) -> t f -> Bool
allF p = getAll #. foldMapF (All #. p)
anyF :: FoldableF t => (forall tp . f tp -> Bool) -> t f -> Bool
anyF p = getAny #. foldMapF (Any #. p)
instance FoldableF (Const x) where
foldMapF _ _ = mempty
class (FunctorF t, FoldableF t) => TraversableF t where
traverseF :: Applicative m
=> (forall s . e s -> m (f s))
-> t e
-> m (t f)
instance TraversableF (Const x) where
traverseF _ (Const x) = pure (Const x)
fmapFDefault :: TraversableF t => (forall s . e s -> f s) -> t e -> t f
fmapFDefault f = runIdentity #. traverseF (Identity #. f)
foldMapFDefault :: (TraversableF t, Monoid m) => (forall s . e s -> m) -> t e -> m
foldMapFDefault f = getConst #. traverseF (Const #. f)
traverseF_ :: (FoldableF t, Applicative f) => (forall s . e s -> f ()) -> t e -> f ()
traverseF_ f = foldrF (\e r -> f e *> r) (pure ())