Reader Monad

Log in om je oplossingen te testen.
-- | Reader is een wrapper rondom een functie, zodat we een groot aantal -- functies die op hetzelfde argument (de omgeving) toegepast worden, kunnen -- combineren. newtype Reader env a = Reader { runReader :: env -> a } -- | Een Reader is een Monad. instance Monad (Reader env) where return = undefined (>>=) = undefined instance Applicative (Reader env) where pure = undefined (<*>) = undefined instance Functor (Reader env) where fmap = undefined -- | Vraag de omgeving op - gelijkaardig aan "get" van State. ask :: Reader env env ask = undefined -- | Voer een gegeven Reader uit binnen een lokaal gewijzigde omgeving. local :: (env -> env') -> (Reader env' a -> Reader env a) local = undefined type Name = String data Term = Add Term Term | App Term Term | Lam Name Term | Var Name | Con Int deriving (Eq, Show) -- Een omgeving werkt hier iets anders dan in de 'Monadische Interpreters' -- oefeningenreeks. Een variabelenaam wordt gemapt op een closure. Een closure -- is een (nog te berekenen) term, tesamen met de context (zelf een omgeving) -- waarin die berekend moet worden. type Env = [(String, Closure)] data Closure = Closure Term Env deriving (Eq, Show) -- Dit geeft ook een iets andere functie-waarde definitie. Een functie bestaat -- uit een variabelenaam en een closure: dus een variabelenaam (die we moeten -- "toekennen"), een term (de "body" die we moeten evalueren) en de context van -- het moment van aanmaken. data Value = Wrong | Num Int | Fun Name Closure deriving (Eq, Show) interp :: Term -> Reader Env Value interp (Con x) = return $ Num x interp (Add e1 e2) = do v1 <- interp e1 v2 <- interp e2 add v1 v2 interp (Lam v e) = do env <- ask return $ Fun v (Closure e env) interp (Var v) = do env <- ask interpClosure (lookup v env) interp (App e1 e2) = do v1 <- interp e1 app v1 e2 -- | Tel twee waarden op - als het getallen zijn. add :: Value -> Value -> Reader Env Value add = undefined -- | Bereken de waarde van een closure - als de closure bestaat. interpClosure :: Maybe Closure -> Reader Env Value interpClosure = undefined -- | Pas een waarde toe op een term - als het een lambda is. app :: Value -> Term -> Reader Env Value app = undefined runInterpreter :: Term -> Value runInterpreter e = runReader (interp e) ([])
Je kunt zo vaak indienen als je wenst. Er wordt enkel rekening gehouden met je laatst ingediende oplossing.
Log in om je oplossingen te testen.