module AST.Class.Functor
( KFunctor(..)
, mappedK1
) where
import AST.Class.Nodes
import AST.Knot (Tree)
import Control.Lens (Setter, sets)
import Data.Functor.Const (Const(..))
import Data.Functor.Product.PolyKinds (Product(..))
import Data.Functor.Sum.PolyKinds (Sum(..))
import Data.Proxy (Proxy(..))
import Prelude.Compat
class KNodes k => KFunctor k where
mapK ::
(forall n. KWitness k n -> Tree p n -> Tree q n) ->
Tree k p ->
Tree k q
instance KFunctor (Const a) where
{-# INLINE mapK #-}
mapK _ (Const x) = Const x
instance (KFunctor a, KFunctor b) => KFunctor (Product a b) where
{-# INLINE mapK #-}
mapK f (Pair x y) =
Pair (mapK (f . E_Product_a) x) (mapK (f . E_Product_b) y)
instance (KFunctor a, KFunctor b) => KFunctor (Sum a b) where
{-# INLINE mapK #-}
mapK f (InL x) = InL (mapK (f . E_Sum_a) x)
mapK f (InR x) = InR (mapK (f . E_Sum_b) x)
{-# INLINE mappedK1 #-}
mappedK1 ::
forall k n p q.
(KFunctor k, KNodesConstraint k ((~) n)) =>
Setter (Tree k p) (Tree k q) (Tree p n) (Tree q n)
mappedK1 = sets (\f -> mapK (Proxy @((~) n) #> f))