{-# language ConstraintKinds #-}
{-# language CPP #-}
{-# language ExistentialQuantification #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language MagicHash #-}
{-# language MultiParamTypeClasses #-}
{-# language PolyKinds #-}
{-# language RankNTypes #-}
{-# language ScopedTypeVariables #-}
{-# language TypeFamilies #-}
{-# language TypeFamilyDependencies #-}
{-# language TypeInType #-}
{-# language UnboxedTuples #-}
module Data.Dependent.Map.Class
( Apply(..)
, Universally(..)
, ApplyUniversally(..)
) where
import Data.Kind (Type,Constraint)
import Data.Proxy (Proxy(..))
import Data.Exists (OrdForall(..),EqForall(..),PrimForall(..))
import Data.Primitive (Prim(..))
import Data.Primitive.Contiguous (Always)
import Data.Primitive.UnliftedArray (PrimUnlifted(..))
import GHC.Exts
newtype Apply f a = Apply (f a)
class ApplyUniversally (f :: k -> Type) (x :: Type -> Constraint) where
applyUniversallyLifted :: forall a y. Proxy f -> Proxy x -> Proxy a -> (x (f a) => y) -> y
#if MIN_VERSION_base(4,10,0)
applyUniversallyUnlifted :: forall a (y :: TYPE 'UnliftedRep). Proxy f -> Proxy x -> Proxy a -> (x (f a) => y) -> y
#else
applyUniversallyUnlifted :: forall a (y :: TYPE 'PtrRepUnlifted). Proxy f -> Proxy x -> Proxy a -> (x (f a) => y) -> y
#endif
class Universally (f :: k -> Type) (x :: Type -> Constraint) where
universally :: Proxy f -> Proxy x -> Proxy a -> (x (Apply f a) => y) -> y
instance ApplyUniversally f PrimUnlifted => PrimUnlifted (Apply f a) where
toArrayArray# (Apply v) = applyUniversallyUnlifted (Proxy :: Proxy f) (Proxy :: Proxy PrimUnlifted) (Proxy :: Proxy a) (toArrayArray# v)
fromArrayArray# a = applyUniversallyLifted (Proxy :: Proxy f) (Proxy :: Proxy PrimUnlifted) (Proxy :: Proxy a) (fromArrayArray# a)
instance EqForall f => Eq (Apply f a) where
Apply x == Apply y = eqForall x y
instance OrdForall f => Ord (Apply f a) where
compare (Apply x) (Apply y) = compareForall x y
instance PrimForall f => Prim (Apply f a) where
sizeOf# _ = sizeOfForall# (proxy# :: Proxy# f)
alignment# _ = alignmentForall# (proxy# :: Proxy# f)
indexByteArray# = coerce (indexByteArrayForall# :: ByteArray# -> Int# -> f a)
readByteArray# = coerce (readByteArrayForall# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, f a #) )
writeByteArray# = coerce (writeByteArrayForall# :: MutableByteArray# s -> Int# -> f a -> State# s -> State# s )
setByteArray# = coerce (setByteArrayForall# :: MutableByteArray# s -> Int# -> Int# -> f a -> State# s -> State# s )
indexOffAddr# = coerce (indexOffAddrForall# :: Addr# -> Int# -> f a)
readOffAddr# = coerce (readOffAddrForall# :: Addr# -> Int# -> State# s -> (# State# s, f a #) )
writeOffAddr# = coerce (writeOffAddrForall# :: Addr# -> Int# -> f a -> State# s -> State# s)
setOffAddr# = coerce (setOffAddrForall# :: Addr# -> Int# -> Int# -> f a -> State# s -> State# s)
instance Universally f Always where
universally _ _ _ y = y
instance ApplyUniversally f Always where
applyUniversallyLifted _ _ _ y = y
applyUniversallyUnlifted _ _ _ y = y
instance ApplyUniversally f PrimUnlifted => Universally f PrimUnlifted where
universally _ _ _ y = y