module Lecture10 where import Data.Map ( Map ) import qualified Data.Map as Map import Control.Applicative import Control.Monad.Reader import Control.Monad.Writer import Control.Monad.State -- ------------------------------------------------- -- Tasks for Reader type Varname = String data AExpr = Con Integer | AVar Varname | Add AExpr AExpr | Mul AExpr AExpr deriving ( Eq, Show, Read ) type AValuation = Map Varname Integer aeval :: AExpr -> AValuation -> Integer aeval (Con x) _ = x aeval (AVar v) vs = Map.findWithDefault 0 v vs aeval (Add x y) vs = aeval x vs + aeval y vs aeval (Mul x y) vs = aeval x vs * aeval y vs subst :: AExpr -> AValuation -> AExpr subst = undefined testAVal :: AValuation testAVal = Map.fromList [("x", 42), ("y", 66), ("z", -100)] -- ------------------------------------------------- -- Task for Writer data Formula = Var String | And Formula Formula | Or Formula Formula | Not Formula deriving (Eq, Ord, Show) type Valuation = Map String Bool eval :: Formula -> Valuation -> Bool eval (Var v) = Map.findWithDefault False v eval (And x y) = do lhs <- eval x if not lhs then pure False else eval y eval (Or x y) = liftA2 (||) (eval x) (eval y) eval (Not x) = not <$> eval x testVal :: Valuation testVal = Map.fromList [("x", True), ("y", False)] -- ------------------------------------------------- -- Tasks for State data BinTree a = Empty | Node a (BinTree a) (BinTree a) deriving (Eq, Show) addIndices :: BinTree a -> BinTree (Integer, a) addIndices t = evalState (addIndices' t) 1 addIndices' :: BinTree a -> State Integer (BinTree (Integer, a)) addIndices' Empty = pure Empty -- passes the state unchanged addIndices' (Node v l r) = undefined addIndicesEnum :: Enum i => BinTree a -> i -> BinTree (i, a) addIndicesEnum t i = undefined sortedBFS :: Ord a => BinTree a -> Bool sortedBFS Empty = True -- you need to handle this separately sortedBFS _ = undefined -- BinTree “pretty” printer ptree :: Show a => BinTree a -> IO () ptree = go 0 where go n Empty = printTreeLine n "-" go n (Node v l r) = do printTreeLine n (show v) let n' = succ n go n' l go n' r printTreeLine n x = putStrLn $ concat (replicate n " ") ++ x tree1 :: BinTree Char tree1 = Node 'a' (Node 'b' (Node 'd' Empty Empty) Empty) (Node 'c' Empty (Node 'e' Empty Empty)) tree2 :: BinTree Char tree2 = Node 'a' (Node 'b' (Node 'c' Empty Empty) Empty) (Node 'd' Empty (Node 'e' Empty Empty)) tree3 :: BinTree String tree3 = Node "root" (Node "l" (Node "ll" Empty (Node "llr" Empty Empty)) (Node "lr" Empty Empty)) (Node "r" Empty (Node "rr" (Node "rrl" Empty Empty) (Node "rrr" Empty Empty)))