{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE GADTs #-}
module Generics.MRSOP.AG where
import Generics.MRSOP.Base
data AnnFix (ki :: kon -> *) (codes :: [[[Atom kon]]]) (phi :: Nat -> *) (n :: Nat) =
AnnFix (phi n) (Rep ki (AnnFix ki codes phi) (Lkup n codes))
getAnn :: AnnFix ki codes ann ix -> ann ix
getAnn (AnnFix a _) = a
annCata :: IsNat ix
=> (forall iy. IsNat iy => chi iy -> Rep ki phi (Lkup iy codes) -> phi iy)
-> AnnFix ki codes chi ix
-> phi ix
annCata f (AnnFix a x) = f a (mapRep (annCata f) x)
forgetAnn :: AnnFix ki codes a ix -> Fix ki codes ix
forgetAnn (AnnFix _ rep) = Fix (mapRep forgetAnn rep)
mapAnn :: (IsNat ix)
=> (forall iy. chi iy -> phi iy)
-> AnnFix ki codes chi ix
-> AnnFix ki codes phi ix
mapAnn f = synthesizeAnn (\x _ -> f x)
synthesize :: forall ki phi codes ix
. (IsNat ix)
=> (forall iy . (IsNat iy) => Rep ki phi (Lkup iy codes) -> phi iy)
-> Fix ki codes ix
-> AnnFix ki codes phi ix
synthesize f = cata alg
where
alg :: forall iy
. (IsNat iy)
=> Rep ki (AnnFix ki codes phi) (Lkup iy codes)
-> AnnFix ki codes phi iy
alg xs = AnnFix (f (mapRep getAnn xs)) xs
synthesizeM :: forall ki phi codes ix m
. (Monad m , IsNat ix)
=> (forall iy . IsNat iy => Rep ki phi (Lkup iy codes) -> m (phi iy))
-> Fix ki codes ix
-> m (AnnFix ki codes phi ix)
synthesizeM f = cataM alg
where
alg :: forall iy
. (IsNat iy)
=> Rep ki (AnnFix ki codes phi) (Lkup iy codes)
-> m (AnnFix ki codes phi iy)
alg xs = flip AnnFix xs <$> f (mapRep getAnn xs)
synthesizeAnn :: forall ki codes chi phi ix
. (IsNat ix)
=> (forall iy. chi iy -> Rep ki phi (Lkup iy codes) -> phi iy)
-> AnnFix ki codes chi ix
-> AnnFix ki codes phi ix
synthesizeAnn f = annCata alg
where
alg :: forall iy
. chi iy
-> Rep ki (AnnFix ki codes phi) (Lkup iy codes)
-> AnnFix ki codes phi iy
alg ann rep = AnnFix (f ann (mapRep getAnn rep)) rep