Opgepast! Het lijkt erop dat je Dodona gebruikt binnen een andere webpagina waardoor mogelijk niet alles goed werkt. Laat dit weten aan je lesgever zodat hij het probleem kan oplossen door een instelling in de leeromgeving aan te passen. Ondertussen kan je op deze link klikken om Dodona te openen in een nieuw venster.
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.