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

时间:2013-12-22 11:09:26

标签: haskell monads monad-transformers

我正在阅读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 个答案:

答案 0 :(得分: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具有更一般的签名,但在开头的一个脚注中说“在2012年移植到更新的GHC”,我认为代码已更新,但文本没有。

修改

我追溯了Map.lookup的变化历史,可追溯到2008年:Code changeTrac ticketLibraries list discussion