summary refs log tree commit diff
path: root/haskell/app/Lift.hs
diff options
context:
space:
mode:
Diffstat (limited to 'haskell/app/Lift.hs')
-rw-r--r--haskell/app/Lift.hs45
1 files changed, 35 insertions, 10 deletions
diff --git a/haskell/app/Lift.hs b/haskell/app/Lift.hs
index 64fa0f6..b503665 100644
--- a/haskell/app/Lift.hs
+++ b/haskell/app/Lift.hs
@@ -21,6 +21,22 @@ factorial =
         )
     )
 
+three :: CExp
+three =
+    ( Let
+        "n"
+        (Atom (Number 1))
+        ( Let
+            "n"
+            (Atom (AAdd (Ident "n") (Number 1)))
+            ( Let
+                "n"
+                (Atom (AAdd (Ident "n") (Number 1)))
+                (FC (Atom (Ident "n")))
+            )
+        )
+    )
+
 liftArgs :: AExp -> AExp
 liftArgs lam@(Lam args body) = Lam (args ++ cata findVarsAExp lam) body
 liftArgs rest = rest
@@ -97,7 +113,7 @@ subVarsCExp (env, queue, LetF name fc rest) =
     let
         (newName, oldNames) =
             foldr
-                (\m (n, ns) -> if n == m then (n ++ "_", n:ns) else (n, ns)) -- repeatedly replace variables in the function call
+                (\m (n, ns) -> if n == m then (n ++ "_", n : ns) else (n, ns)) -- repeatedly replace variables in the function call
                 (name, [])
                 queue -- make sure to do oldest first!
         newFC = foldr replaceVarsFC fc $ oldNames \\ [newName]
@@ -110,15 +126,24 @@ subVarsCExp (env, queue, IfF cond thenPart elsePart) =
         (env, queue, elsePart)
 subVarsCExp (env, queue, FCF fc) = FCF $ foldr replaceVarsFC fc queue
 
-
+unsafeCotransverse ::
+    (Corecursive t, Recursive a, Functor f) =>
+    (f (Base a a) -> Base t (f a)) ->
+    f a ->
+    t
 unsafeCotransverse n = ana (n . fmap project)
 
-subVarsCExp' (env, LetF name fc body) 
-            | name `elem` env =
-              let
-                newName = name ++ "_"
-                newFC = replaceVarsFC newName fc
-                newBody = cata replaceVarsCExp body name
-              in LetF newName newFC (newName : env, newBody)
-            | otherwise = LetF name fc (name : env, body)
+subVarsCExp' :: ([String], CExpF CExp) -> CExpF ([String], CExp)
+subVarsCExp' (env, LetF name fc body)
+    | name `elem` env =
+        let
+            newName = name ++ "_"
+            newFC = replaceVarsFC newName fc
+            newBody = cata replaceVarsCExp body name
+         in
+            LetF newName newFC (newName : env, newBody)
+    | otherwise = LetF name fc (name : env, body)
 subVarsCExp' (env, rest) = fmap (env,) rest
+
+substitute :: CExp -> CExp
+substitute = unsafeCotransverse subVarsCExp' . ([],)