module AST.Class.Foldable
( KFoldable(..)
, foldMapK1
, traverseK_, traverseK1_
) where
import AST.Class.Nodes (KNodes(..), KWitness(..), (#>))
import AST.Knot (Tree)
import Data.Foldable (sequenceA_)
import Data.Functor.Const (Const(..))
import Data.Proxy (Proxy(..))
import Data.Functor.Product.PolyKinds (Product(..))
import Data.Functor.Sum.PolyKinds (Sum(..))
import Prelude.Compat
class KNodes k => KFoldable k where
foldMapK ::
Monoid a =>
(forall n. KWitness k n -> Tree p n -> a) ->
Tree k p ->
a
instance KFoldable (Const a) where
{-# INLINE foldMapK #-}
foldMapK _ _ = mempty
instance (KFoldable a, KFoldable b) => KFoldable (Product a b) where
{-# INLINE foldMapK #-}
foldMapK f (Pair x y) = foldMapK (f . E_Product_a) x <> foldMapK (f . E_Product_b) y
instance (KFoldable a, KFoldable b) => KFoldable (Sum a b) where
{-# INLINE foldMapK #-}
foldMapK f (InL x) = foldMapK (f . E_Sum_a) x
foldMapK f (InR x) = foldMapK (f . E_Sum_b) x
{-# INLINE foldMapK1 #-}
foldMapK1 ::
forall a k n p.
( Monoid a, KFoldable k
, KNodesConstraint k ((~) n)
) =>
(Tree p n -> a) ->
Tree k p ->
a
foldMapK1 f = foldMapK (Proxy @((~) n) #> f)
{-# INLINE traverseK_ #-}
traverseK_ ::
(Applicative f, KFoldable k) =>
(forall c. KWitness k c -> Tree m c -> f ()) ->
Tree k m ->
f ()
traverseK_ f = sequenceA_ . foldMapK (fmap (:[]) . f)
{-# INLINE traverseK1_ #-}
traverseK1_ ::
forall f k n p.
( Applicative f, KFoldable k
, KNodesConstraint k ((~) n)
) =>
(Tree p n -> f ()) ->
Tree k p ->
f ()
traverseK1_ f = traverseK_ (Proxy @((~) n) #> f)