hypertypes-0.2.2: src/Hyper/Class/Morph.hs
{-# LANGUAGE FlexibleInstances #-}
-- | An extension of 'HFunctor' for parameterized 'Hyper.Type.HyperType's
module Hyper.Class.Morph
( HMorph (..)
, HMorphWithConstraint
, morphTraverse
, (#?>)
, HIs2
, morphMapped1
, morphTraverse1
) where
import Control.Lens (Setter, sets)
import Data.Kind (Type)
import Hyper.Class.Traversable (ContainedH (..), HTraversable (..))
import Hyper.Type (HyperType, type (#))
import Hyper.Internal.Prelude
-- | A type-varying variant of 'HFunctor' which can modify type parameters of the mapped 'HyperType'
class HMorph s t where
type MorphConstraint s t (c :: (HyperType -> HyperType -> Constraint)) :: Constraint
data MorphWitness s t :: HyperType -> HyperType -> Type
morphMap ::
(forall a b. MorphWitness s t a b -> p # a -> q # b) ->
s # p ->
t # q
morphLiftConstraint ::
MorphConstraint s t c =>
MorphWitness s t a b ->
Proxy c ->
(c a b => r) ->
r
type HMorphWithConstraint s t c = (HMorph s t, MorphConstraint s t c)
-- | 'HTraversable' extended with support of changing type parameters of the 'HyperType'
morphTraverse ::
(Applicative f, HMorph s t, HTraversable t) =>
(forall a b. MorphWitness s t a b -> p # a -> f (q # b)) ->
s # p ->
f (t # q)
morphTraverse f = hsequence . morphMap (fmap MkContainedH . f)
(#?>) ::
(HMorph s t, MorphConstraint s t c) =>
Proxy c ->
(c a b => r) ->
MorphWitness s t a b ->
r
(#?>) p r w = morphLiftConstraint w p r
class (i0 ~ t0, i1 ~ t1) => HIs2 (i0 :: HyperType) (i1 :: HyperType) t0 t1
instance HIs2 a b a b
morphMapped1 ::
forall a b s t p q.
HMorphWithConstraint s t (HIs2 a b) =>
Setter (s # p) (t # q) (p # a) (q # b)
morphMapped1 = sets (\f -> morphMap (Proxy @(HIs2 a b) #?> f))
morphTraverse1 ::
(HMorphWithConstraint s t (HIs2 a b), HTraversable t) =>
Traversal (s # p) (t # q) (p # a) (q # b)
morphTraverse1 f = hsequence . (morphMapped1 %~ MkContainedH . f)