{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
module Barbies.Generics.Functor
( GFunctor(..)
)
where
import Data.Generics.GenericN
import Data.Proxy (Proxy (..))
import GHC.TypeLits (Nat)
class GFunctor (n :: Nat) f g repbf repbg where
gmap :: Proxy n -> (forall a . f a -> g a) -> repbf x -> repbg x
instance
( GFunctor n f g bf bg
) => GFunctor n f g (M1 i c bf) (M1 i c bg)
where
gmap pn h = M1 . gmap pn h . unM1
{-# INLINE gmap #-}
instance GFunctor n f g V1 V1 where
gmap _ _ _ = undefined
instance GFunctor n f g U1 U1 where
gmap _ _ = id
{-# INLINE gmap #-}
instance
( GFunctor n f g l l'
, GFunctor n f g r r'
)
=> GFunctor n f g (l :*: r) (l' :*: r')
where
gmap pn h (l :*: r) = (gmap pn h l) :*: gmap pn h r
{-# INLINE gmap #-}
instance
( GFunctor n f g l l'
, GFunctor n f g r r'
) => GFunctor n f g (l :+: r) (l' :+: r')
where
gmap pn h = \case
L1 l -> L1 (gmap pn h l)
R1 r -> R1 (gmap pn h r)
{-# INLINE gmap #-}
type P = Param
instance
GFunctor n f g (Rec (P n f a') (f a))
(Rec (P n g a') (g a))
where
gmap _ h (Rec (K1 fa)) = Rec (K1 (h fa))
{-# INLINE gmap #-}
instance
( Functor h
) =>
GFunctor n f g (Rec (h (P n f a')) (h (f a)))
(Rec (h (P n g a')) (h (g a)))
where
gmap _ h (Rec (K1 hfa)) = Rec (K1 (h <$> hfa))
{-# INLINE gmap #-}
instance
GFunctor n f g (Rec x x) (Rec x x)
where
gmap _ _ = id
{-# INLINE gmap #-}