首页 文章

Monad变形金刚文件:eval1没有进行类型检查

提问于
浏览
3

我正在阅读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

另一种具有monadic风格的评估函数:

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的失败函数返回Nothing,而Identity monad中的失败函数抛出异常,这将导致不同的错误消息 . )

但是 Map.lookup 被定义为可以与任何monad一起使用吗? (它的类型签名表示它返回 Maybe 值 . )

1 回答

  • 4

    我实际上在 eval1 的文档中看到了这个代码,它应该很好地检查(我重新缩进它):

    eval1 env (Var n) =
        maybe (fail ("undefined variable: " ++ n)) return $
            Map.lookup n env
    

    似乎 Map.lookup 之前做过更普遍的签名:http://hackage.haskell.org/package/containers-0.1.0.0/docs/Data-Map.html

    由于该文档的日期是2006年,并且仍然有上面引用的文本,说明 Map.lookup 具有更一般的签名,但在开头说一个脚注"Ported to newer GHC in 2012",我认为代码已更新但文本没有 .

    Edit:

    我追溯了自2008年以来 Map.lookup 的变化历史:Code changeTrac ticketLibraries list discussion

相关问题