{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module AST.Class.Apply
( KApply(..), KApplicative
, liftK2
) where
import AST.Class.Functor (KFunctor(..))
import AST.Class.Nodes (KNodes(..))
import AST.Class.Pointed (KPointed)
import AST.Knot (Tree)
import Data.Functor.Const (Const(..))
import Data.Functor.Product.PolyKinds (Product(..))
import Prelude.Compat
class KFunctor k => KApply k where
zipK ::
Tree k p ->
Tree k q ->
Tree k (Product p q)
class (KPointed k, KApply k) => KApplicative k
instance (KPointed k, KApply k) => KApplicative k
instance Semigroup a => KApply (Const a) where
{-# INLINE zipK #-}
zipK (Const x) (Const y) = Const (x <> y)
instance (KApply a, KApply b) => KApply (Product a b) where
{-# INLINE zipK #-}
zipK (Pair a0 b0) (Pair a1 b1) = Pair (zipK a0 a1) (zipK b0 b1)
{-# INLINE liftK2 #-}
liftK2 ::
KApply k =>
(forall n. KWitness k n -> Tree p n -> Tree q n -> Tree r n) ->
Tree k p ->
Tree k q ->
Tree k r
liftK2 f x = mapK (\w (Pair a b) -> f w a b) . zipK x