{-# LANGUAGE TypeOperators #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} -- The reason why this is a separate module with little in it: {-# LANGUAGE AllowAmbiguousTypes #-} module AST.Weaken where data env :> env' where WId :: env :> env WSink :: env :> (t : env) WCopy :: env :> env' -> (t : env) :> (t : env') WPop :: (t : env) :> env' -> env :> env' WThen :: env1 :> env2 -> env2 :> env3 -> env1 :> env3 WClosed :: '[] :> env deriving instance Show (env :> env') (.>) :: env2 :> env3 -> env1 :> env2 -> env1 :> env3 (.>) = flip WThen type family Append a b where Append '[] l = l Append (x : xs) l = x : Append xs l data ListSpine list where LSNil :: ListSpine '[] LSCons :: ListSpine list -> ListSpine (t : list) class KnownListSpine list where knownListSpine :: ListSpine list instance KnownListSpine '[] where knownListSpine = LSNil instance KnownListSpine list => KnownListSpine (t : list) where knownListSpine = LSCons knownListSpine wSinks :: forall list env. KnownListSpine list => env :> Append list env wSinks = go (knownListSpine :: ListSpine list) where go :: forall list'. ListSpine list' -> env :> Append list' env go LSNil = WId go (LSCons spine) = WSink .> go spine