【问题标题】:Monad Transformers document: eval1 doesn't typecheckMonad Transformers 文档:eval1 不进行类型检查
【发布时间】: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


    【解决方案1】:

    我实际上在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

    【讨论】:

    • 谢谢,但我在该文档中找不到您上面提到的代码。你能告诉它是什么页码吗? (我指出的pdf文档中eval1的代码在第4页是这样的:eval1 env (Var n) = Map.lookup n env
    • 我看到了我在第 4 页下面大约 2/3 处引用的代码。您可能需要获得一份新副本或其他什么?脚注表明该文件于 2012 年更新。
    • 抱歉,我有一份旧文件。
    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多