{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Data.Extensible.Inclusion (
type (⊆)
, Include
, inclusion
, shrink
, spread
, IncludeAssoc
, Associated
, Associated'
, inclusionAssoc
, shrinkAssoc
, spreadAssoc
) where
import Data.Constraint
import Data.Extensible.Class
import Data.Extensible.Product
import Data.Extensible.Sum
import Data.Extensible.Internal.Rig
import Data.Proxy
type xs ⊆ ys = Include ys xs
type Include ys = Forall (Member ys)
inclusion :: forall xs ys. Include ys xs => xs :& Membership ys
inclusion = hrepeatFor (Proxy :: Proxy (Member ys)) membership
{-# INLINABLE inclusion #-}
shrink :: (xs ⊆ ys) => ys :& h -> xs :& h
shrink h = hmap (hindex h) inclusion
{-# INLINE shrink #-}
spread :: (xs ⊆ ys) => xs :/ h -> ys :/ h
spread (EmbedAt i h) = views (pieceAt i) EmbedAt inclusion h
{-# INLINE spread #-}
type family Associated' (xs :: [Assoc k v]) (t :: Assoc k v) :: Constraint where
Associated' xs (k ':> v) = Lookup xs k v
class Associated' xs t => Associated xs t where
getAssociation :: Membership xs t
instance (Associated' xs t, t ~ (k ':> v)) => Associated xs t where
getAssociation = association
type IncludeAssoc ys = Forall (Associated ys)
inclusionAssoc :: forall xs ys. IncludeAssoc ys xs => xs :& Membership ys
inclusionAssoc = hrepeatFor (Proxy :: Proxy (Associated ys)) getAssociation
{-# INLINABLE inclusionAssoc #-}
shrinkAssoc :: (IncludeAssoc ys xs) => ys :& h -> xs :& h
shrinkAssoc h = hmap (hindex h) inclusionAssoc
{-# INLINE shrinkAssoc #-}
spreadAssoc :: (IncludeAssoc ys xs) => xs :/ h -> ys :/ h
spreadAssoc (EmbedAt i h) = views (pieceAt i) EmbedAt inclusionAssoc h
{-# INLINE spreadAssoc #-}