Warning! It seems that you are using Dodona within another webpage, so not everything may work properly. Let your teacher know so that he can solve the problem by adjusting a setting in the learning environment. In the meantime, you can click this link to open Dodona in a new window.
Reader Monad
Sign in to test your solution.
-- | 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) ([])
You can submit as many times as you like. Only your latest submission will be taken into account.
Sign in to test your solution.