Map.lookup的Maybe结果不是我的Monad Transformer堆栈的类型检查

时间:2015-08-08 21:13:50

标签: haskell dictionary monads monad-transformers maybe

我将通过以下文件:Monad Transformers Step by Step。在第2.1节“转换为Monadic样式”中,函数转换为Value monad中的Eval1。这部分功能对我来说没有意义:

eval1 env (Var n) = Map.lookup n env

结果将是Maybe Value,但函数的类型签名是:

eval1 :: Env → Exp → Eval1 Value

该函数未能键入check,错误对我来说似乎很明显。然而,作者明确指出这将有效:

  

... Var案例不再需要fromJust调用了:原因是Map.lookup被定义为只需调用monad的失败函数就可以在任何monad中工作 - 这非常适合我们的monadic表达式。

Map.lookup的签名看起来不像是用于任何monad:

lookup :: Ord k => k -> Map k a -> Maybe a

这篇论文是否已过时或我遗失了什么?如果论文实际上已过时,为什么lookup更改为仅与Maybe一起使用。

谢谢!

1 个答案:

答案 0 :(得分:14)

你的教程是从2006年开始的。它使用的是a very old version of Data.Map lookup的类型确实是:

lookup :: (Monad m, Ord k) => k -> Map k a -> m a

我认为发生了变化,因为fail被广泛认为是Monad类中的疣。返回Maybe a会使查找失败变得明确且易于管理。将它隐藏在fail之后隐藏它只是为了让一个稍微方便的类型是非常脏的IMO。 (另见the question linked to by Ørjan。)

您可以使用此lookup的改编版本来完成教程:

fallibleLookup :: (Ord k, Monad m) => k -> Map.Map k a -> m a
fallibleLookup k = maybe (fail "fallibleLookup: Key not found") pure . Map.lookup k

请注意,with the upcoming release of GHC 8.8 m上使用的正确约束将是MonadFail而不是Monad