summaryrefslogtreecommitdiff
path: root/src/AST/Weaken.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/AST/Weaken.hs')
-rw-r--r--src/AST/Weaken.hs43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/AST/Weaken.hs b/src/AST/Weaken.hs
new file mode 100644
index 0000000..56b7a74
--- /dev/null
+++ b/src/AST/Weaken.hs
@@ -0,0 +1,43 @@
+{-# 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
+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