I'm reading through the Monad Transformer document. And I have come across this code sample:
import qualified Data.Map as Map
import Control.Monad.Identity
type Eval1 a = Identity a
runEval1 :: Eval1 a -> a
runEval1 ev = runIdentity ev
type Name = String
data Exp = Lit Integer
| Var Name
| Plus Exp Exp
| Abs Name Exp
| App Exp Exp
deriving (Show)
data Value = IntVal Integer
| FunVal Env Name Exp
type Env = Map.Map Name Value
And they write evaluation function for that:
eval0 :: Env -> Exp -> Value
eval0 env (Var i) = fromJust $ Map.lookup i env
And another evaluation function with monadic style:
eval1 :: Env -> Exp -> Eval1 Value
eval1 env (Var n) = Map.lookup n env
(I'm just showing part of the eval1
function where I have problem)
The eval0
function typechecks but eval1
doesn't typecheck. So is this error in that document or am I missing something ?
Also they go on explaining about eval1
like this:
Var case does not need a fromJust call anymore: The reason is that Map.lookup is defined to work within any monad by simply calling the monad’s fail function – this fits nicely with our monadic formulation here. (The fail function of the Maybe monad returns Nothing, whereas the fail function in the Identity monad throws an exception, which will lead to different error messages.)
But is Map.lookup
defined to work with any monad ? (It's type signature indicates that it retuns a Maybe
value.)