diff options
author | Camil Staps | 2017-11-21 23:47:34 +0100 |
---|---|---|
committer | Camil Staps | 2017-11-21 23:47:34 +0100 |
commit | fe5e47abf8fea9bc0b7fcc245e3a24cc8d142303 (patch) | |
tree | 9921f4fd4170d2aa033b75f7e51dc10888fda0f1 | |
parent | Make App infix @ (diff) |
Deal with functions using an argument more than once
-rw-r--r-- | pf.icl | 15 |
1 files changed, 12 insertions, 3 deletions
@@ -47,17 +47,25 @@ optim :: Expr -> Expr optim (Lambda id e) | hasIdent id e = case optim e of Ident id` -> if (id == id`) (Ident "id") (Ident "const" @ e) - f @ x -> case moveOutside id (f @ x) of - a=:(f @ Ident id`) -> if (id == id`) f (Ident "const" @ a) - a -> Ident "const" @ a + e=:(f @ x) -> optim (optApp e) e -> Lambda id e | otherwise = Ident "const" @ optim e +where + optApp :: Expr -> Expr + optApp (f @ x) + | hasIdent id f && hasIdent id x = Ident "ap" @ Lambda id f @ Lambda id x + | otherwise = case moveOutside id (f @ x) of + a=:(f @ Ident id`) -> if (id == id`) f (Ident "const" @ a) + a -> Ident "const" @ a +optim (Ident "flip" @ Ident "ap" @ Ident "id") = Ident "join" +optim (f @ x) = optim f @ optim x optim e = e moveOutside :: Ident Expr -> Expr moveOutside _ (Ident id) = Ident id moveOutside _ (Literal l) = Literal l moveOutside id (f @ x) +| hasIdent id f && hasIdent id x = abort "moveOutside on @ with id in both sides" | hasIdent id f = case moveOutside id f of Ident id -> Ident "flip" @ Ident "id" @ x @ Ident id g @ Ident id -> Ident "flip" @ g @ x @ Ident id @@ -81,6 +89,7 @@ Start = map do , Lambda "x" (Lambda "y" (Ident "y" @ Ident "x")) , Lambda "x" (Lambda "y" (Ident "y" @ Literal (LitInt 10))) , Lambda "f" (Lambda "a" (Lambda "b" (Lambda "c" (Lambda "d" (Ident "f" @ Ident "b" @ Ident "c" @ Ident "d" @ Ident "a"))))) + , Lambda "f" (Lambda "x" (Ident "f" @ Ident "x" @ Ident "x")) ] where do e = (print e, " ==> ", print (optim e), "\n") |