hypertypes-0.1.0.2: src/Hyper/Combinator/Ann.hs
{-# LANGUAGE TemplateHaskell, UndecidableInstances, FlexibleInstances #-}
module Hyper.Combinator.Ann
( Ann(..), hAnn, hVal
, Annotated, annotation, annValue
) where
import Control.Lens (Lens, Lens', _Wrapped, from)
import Hyper.Class.Foldable (HFoldable(..))
import Hyper.Class.Functor (HFunctor(..))
import Hyper.Class.Nodes
import Hyper.Class.Traversable
import Hyper.Combinator.Flip
import Hyper.Recurse
import Hyper.TH.Traversable (makeHTraversableApplyAndBases)
import Hyper.Type (type (#), type (:#))
import Hyper.Internal.Prelude
data Ann a h = Ann
{ _hAnn :: a h
, _hVal :: h :# Ann a
} deriving Generic
makeLenses ''Ann
makeHTraversableApplyAndBases ''Ann
makeCommonInstances [''Ann]
instance RNodes h => HNodes (HFlip Ann h) where
type HNodesConstraint (HFlip Ann h) c = (Recursive c, c h)
type HWitnessType (HFlip Ann h) = HRecWitness h
hLiftConstraint (HWitness HRecSelf) = \_ x -> x
hLiftConstraint (HWitness (HRecSub w0 w1)) = hLiftConstraintH w0 w1
-- TODO: Dedup this and similar code in Hyper.Unify.Generalize
hLiftConstraintH ::
forall a c b n r.
(RNodes a, HNodesConstraint (HFlip Ann a) c) =>
HWitness a b -> HRecWitness b n -> Proxy c -> (c n => r) -> r
hLiftConstraintH c n p f =
withDict (recurse (Proxy @(RNodes a))) $
withDict (recurse (Proxy @(c a))) $
hLiftConstraint c (Proxy @RNodes)
( hLiftConstraint c p
(hLiftConstraint (HWitness @(HFlip Ann _) n) p f)
)
instance RNodes a => RNodes (Ann a) where
{-# INLINE recursiveHNodes #-}
recursiveHNodes _ = withDict (recursiveHNodes (Proxy @a)) Dict
instance (c (Ann a), Recursively c a) => Recursively c (Ann a) where
{-# INLINE recursively #-}
recursively _ = withDict (recursively (Proxy @(c a))) Dict
instance RTraversable a => RTraversable (Ann a) where
{-# INLINE recursiveHTraversable #-}
recursiveHTraversable _ = withDict (recursiveHTraversable (Proxy @a)) Dict
instance Recursively HFunctor h => HFunctor (HFlip Ann h) where
{-# INLINE hmap #-}
hmap f =
withDict (recursively (Proxy @(HFunctor h))) $
_HFlip %~
\(Ann a b) ->
Ann
(f (HWitness HRecSelf) a)
(hmap
( Proxy @(Recursively HFunctor) #*#
\w -> from _HFlip %~ hmap (f . HWitness . HRecSub w . (^. _HWitness))
) b
)
instance Recursively HFoldable h => HFoldable (HFlip Ann h) where
{-# INLINE hfoldMap #-}
hfoldMap f (MkHFlip (Ann a b)) =
withDict (recursively (Proxy @(HFoldable h))) $
f (HWitness HRecSelf) a <>
hfoldMap
( Proxy @(Recursively HFoldable) #*#
\w -> hfoldMap (f . HWitness . HRecSub w . (^. _HWitness)) . MkHFlip
) b
instance RTraversable h => HTraversable (HFlip Ann h) where
{-# INLINE hsequence #-}
hsequence =
withDict (recurse (Proxy @(RTraversable h))) $
_HFlip
( \(Ann a b) ->
Ann
<$> runContainedH a
<*> htraverse (Proxy @RTraversable #> from _HFlip hsequence) b
)
type Annotated a = Ann (Const a)
annotation :: Lens' (Annotated a # h) a
annotation = hAnn . _Wrapped
-- | Polymorphic lens to an @Annotated@ value
annValue :: Lens (Annotated a # h0) (Annotated a # h1) (h0 # Annotated a) (h1 # Annotated a)
annValue f (Ann (Const a) b) = f b <&> Ann (Const a)