From e219436446d1ba4f77b915d546ce13711f5c1254 Mon Sep 17 00:00:00 2001 From: pingu Date: Mon, 17 Nov 2025 19:36:26 +0100 Subject: [PATCH] Yippie --- 3/Assignment.hs | 39 +++++++++++++++++++++++++++++++-------- 3/chi.cabal | 8 +++++--- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/3/Assignment.hs b/3/Assignment.hs index de206ff..69ebd3b 100644 --- a/3/Assignment.hs +++ b/3/Assignment.hs @@ -1,25 +1,48 @@ -{-# Language LambdaCase #-} +{-# Language LambdaCase, Strict #-} module Assignment where import Chi +import Control.Monad +import Control.Monad.Identity +import Debug.Trace (trace) +import Data.HashMap.Strict (HashMap) +import qualified Data.HashMap.Strict as HM +import Data.Functor ( (<&>) ) +import Control.Monad.Identity (Identity(runIdentity)) subst :: Variable -> Exp -> Exp -> Exp subst var e = \case Apply e1 e2 -> Apply (subst var e e1) (subst var e e2) - Lambda x e' -> Lambda x $ if var /= x then (subst var e e') else e' + Lambda x e' -> Lambda x $ if var /= x then subst var e e' else e' Var x -> if var == x then e else Var x Const c es -> Const c $ map (subst var e) es - Rec x e' -> Rec x $ if var /= x then (subst var e e') else e' - Case e' branches -> Case (subst var e e') $ map substBr branches + Rec x e' -> Rec x $ if var /= x then subst var e e' else e' + Case e' bs -> Case (subst var e e') $ map substBr bs where substBr :: Br -> Br - substBr (Branch c vs e') = Branch c vs $ if var `notElem` vs then (subst var e e') else e' + substBr (Branch c vs e') = Branch c vs $ if var `notElem` vs then subst var e e' else e' -eval' :: Exp -> Reader (Map Variable Exp) Exp -eval' = undefined +lookupBranch :: Constructor -> [Br] -> Identity ([Variable], Exp) +lookupBranch c [] = error "No matching branch" +lookupBranch c ((Branch c' bs e):brs) = if c == c' then pure (bs,e) else lookupBranch c brs + +eval' :: Exp -> Identity Exp +eval' = \case + e@(Apply e1 e2) -> eval' e1 >>= \case + Lambda x e' -> eval' e2 >>= eval' . flip (subst x) e' + _ -> error $ "Function was not function in evaluation: " <> show e + Const c es -> mapM eval' es <&> Const c + Rec x e -> eval' $ subst x (Rec x e) e + Case e bs -> eval' e >>= \case + Const c vs -> lookupBranch c bs >>= \case + (xs,e') -> + if length vs /= length xs then error "Not the same amount of arguments in case" else + eval' $ foldr (uncurry subst) e' (zip xs vs) + e -> error $ "Non const in case: " <> show e + x -> pure x eval :: Exp -> Exp -eval = undefined +eval = runIdentity . eval' main :: IO () main = getLine >>= print . eval . parse diff --git a/3/chi.cabal b/3/chi.cabal index 7ee5807..18e7537 100644 --- a/3/chi.cabal +++ b/3/chi.cabal @@ -12,12 +12,12 @@ library hashable >= 1.4.7.0 && < 1.6, mtl >= 2.2.2 && < 2.4, pretty ^>= 1.1.3.6, - QuickCheck ^>= 2.15.0.0, + QuickCheck ^>= 2.16.0.0, transformers >= 0.5.6.2 && < 0.7, unordered-containers ^>= 0.2.20 build-tool-depends: - alex:alex ^>= 3.5.2.0, - happy:happy ^>= 2.1.5 + alex:alex ^>= 3.5.4.0, + happy:happy ^>= 2.1.7 exposed-modules: AbsChi Chi @@ -31,3 +31,5 @@ executable interpreter main-is: Assignment.hs build-depends: base , chi + , mtl + , unordered-containers