{-# LANGUAGE GADTs,
KindSignatures,
TypeOperators,
TypeFamilies,
MultiParamTypeClasses,
FlexibleInstances,
FlexibleContexts,
StandaloneDeriving,
UndecidableInstances,
FunctionalDependencies,
ConstraintKinds,
ScopedTypeVariables,
PolyKinds,
DataKinds
#-}
module Language.Grammars.AspectAG.TPrelude where
import Data.Kind
import Data.Type.Equality
import GHC.TypeLits
import Data.Proxy
data Label l = Label
sndLabel :: Label '(a,b) -> Label b
sndLabel _ = undefined
getProxy :: a -> Proxy a ; getProxy _ = Proxy
getLabel :: a -> Label a ; getLabel _ = Label
proxyFrom :: t a -> Proxy a
proxyFrom _ = Proxy
type family If (cond:: Bool) (thn :: k) (els :: k) :: k where
If 'True thn els = thn
If 'False thn els = els
type family Or (l :: Bool)(r :: Bool) :: Bool where
Or False b = b
Or True b = 'True
type family And (l :: Bool)(r :: Bool) :: Bool where
And False b = False
And True b = b
type family Not (l :: Bool) :: Bool where
Not False = True
Not True = False
type family LabelSetF (r :: [(k, k')]) :: Bool where
LabelSetF '[] = True
LabelSetF '[ '(l, v)] = True
LabelSetF ( '(l, v) ': '(l', v') ': r) = And3 (Not (l == l'))
(LabelSetF ( '(l, v) ': r) )
(LabelSetF ( '(l', v') ': r) )
type LabelSet r = LabelSetF r ~ True
type family And3 (a1 :: Bool) (a2 :: Bool) (a3 :: Bool) where
And3 True True True = True
And3 _ _ _ = False
type family HMemberT (e::k)(l ::[k]) :: Bool where
HMemberT k '[] = 'False
HMemberT k ( k' ': l) = If (k==k') 'True (HMemberT k l)
type family HasLabelT (l::k) (lst :: [(k,Type)]) :: Bool where
HasLabelT l '[] = 'False
HasLabelT l ( '(k,v) ': tail) = If (l == k) 'True (HasLabelT l tail)
class HEq (x :: k) (y :: k) (b :: Bool) | x y -> b
type HEqK (x :: k1) (y :: k2) (b :: Bool) = HEq (Proxy x) (Proxy y) b
instance ((Proxy x == Proxy y) ~ b) => HEq x y b
type family HEqKF (a :: k)(b :: k) :: Bool
type instance HEqKF a b = a == b
type family (a :: k1) === (b :: k2) where
a === b = (Proxy a) == (Proxy b)
type family TPair (a :: k) b where
TPair a b = '(a, b)
type family LabelsOf (r :: [(k, k')]) :: [k] where
LabelsOf '[] = '[]
LabelsOf ( '(k, ks) ': ls) = k ': LabelsOf ls
type family HasLabel (l :: k) (r :: [(k, k')]) :: Bool where
HasLabel l '[] = False
HasLabel l ( '(l', v) ': r) = Or (l == l') (HasLabel l r)
type family Equal (a:: k)(b :: k') :: Bool where
Equal a a = True
Equal a b = False