【发布时间】:2013-12-22 11:09:26
【问题描述】:
我正在阅读Monad Transformer 文档。 我遇到了这个代码示例:
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
他们为此编写了评估函数:
eval0 :: Env -> Exp -> Value
eval0 env (Var i) = fromJust $ Map.lookup i env
还有一个单子风格的评估函数:
eval1 :: Env -> Exp -> Eval1 Value
eval1 env (Var n) = Map.lookup n env
(我只是展示了我有问题的eval1函数的一部分)
eval0 函数进行类型检查,但 eval1 不进行类型检查。那么是该文档中的错误还是我遗漏了什么?
他们还继续像这样解释eval1:
var case 不再需要 fromJust 调用:原因是 Map.lookup 被定义为在任何 monad 中工作,只需调用 monad 的失败函数——这与我们的 monadic 公式非常吻合 这里。 (Maybe monad 的 fail 函数返回 Nothing,而 Identity monad 中的 fail 函数抛出一个异常,它 会导致不同的错误信息。)
但是 Map.lookup 是否定义为与任何 monad 一起使用? (它的类型签名表明它返回一个Maybe 值。)
【问题讨论】:
标签: haskell monads monad-transformers