-- | Illusration of applicative functors in action. module Applicative where import Control.Applicative (liftA2) -- * Environments -- | Variable names. type Var = String -- | An environment mapping variables to integers. type Env a = Var -> Maybe a -- | An empty environment. Maps all uninitialized variables to 0. empty :: Env a empty = \x -> Nothing -- | Set a variable to a value in the environment. set :: Eq a => Var -> a -> Env a -> Env a set x i m = \y -> if x == y then Just i else m y -- | Lookup the value for a variable in the environment. get :: Var -> Env a -> Maybe a get x m = m x -- * Expression language -- | Simple arithmetic expressions with variables. data Expr = Lit Int | Ref Var | Neg Expr | Bin Op Expr Expr deriving (Eq,Show) -- | Binary operators. data Op = Add | Mul deriving (Eq,Show) -- | Function corresponding to each binary operator. op :: Op -> Int -> Int -> Int op Add = (+) op Mul = (*) -- | Here's our not-to-bad evaluation function. eval :: Env Int -> Expr -> Maybe Int eval m (Lit i) = Just i eval m (Ref x) = get x m eval m (Neg e) = case eval m e of Just i -> Just (negate i) _ -> Nothing eval m (Bin o l r) = case (eval m l, eval m r) of (Just i, Just j) -> Just (op o i j) _ -> Nothing -- | Now making use of the Functor and Applicative interfaces. evalA :: Env Int -> Expr -> Maybe Int evalA = undefined