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

问题描述 投票:10回答:1

我将通过以下论文: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

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

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

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

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

这篇论文是否已过时或者我遗失了什么?如果论文实际上已经过时,为什么lookup改为仅与Maybe合作。

谢谢!

haskell dictionary monads monad-transformers maybe
1个回答
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.8m上使用的正确约束将是MonadFail而不是Monad

© www.soinside.com 2019 - 2024. All rights reserved.