Map.lookup 的 Maybe 结果不是使用我的 Monad Transformer 堆栈进行类型检查
The Maybe result from Map.lookup is not type checking with my Monad Transformer stack
我正在阅读以下论文:Monad Transformers Step by Step。在 2.1 节 "Converting to Monadic Style" 中,函数在 Eval1
monad 中被转换为 return Value
。这部分功能对我来说没有意义:
eval1 env (Var n) = Map.lookup n env
结果将是 Maybe Value
但是函数的类型签名是:
eval1 :: Env → Exp → Eval1 Value
该函数无法进行类型检查,这个错误对我来说似乎很明显。然而作者明确指出这将起作用:
... the Var case does not need a fromJust call anymore: The reason is that Map.lookup is defined to work within any monad by simply calling the monad’s fail function – this fits nicely with our monadic formulation here.
Map.lookup 的签名看起来不像是为与任何 monad 一起工作而设计的:
lookup :: Ord k => k -> Map k a -> Maybe a
这篇论文过时了还是我遗漏了什么?如果论文实际上已经过时,为什么 lookup
改为仅适用于 Maybe
。
谢谢!
您的教程是 2006 年的。它使用 a very old version of Data.Map
,其中 lookup
的类型确实是:
lookup :: (Monad m, Ord k) => k -> Map k a -> m a
我认为发生这种变化是因为 fail
在 Monad
class 中被广泛认为是一个疣。返回 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
。
我正在阅读以下论文:Monad Transformers Step by Step。在 2.1 节 "Converting to Monadic Style" 中,函数在 Eval1
monad 中被转换为 return Value
。这部分功能对我来说没有意义:
eval1 env (Var n) = Map.lookup n env
结果将是 Maybe Value
但是函数的类型签名是:
eval1 :: Env → Exp → Eval1 Value
该函数无法进行类型检查,这个错误对我来说似乎很明显。然而作者明确指出这将起作用:
... the Var case does not need a fromJust call anymore: The reason is that Map.lookup is defined to work within any monad by simply calling the monad’s fail function – this fits nicely with our monadic formulation here.
Map.lookup 的签名看起来不像是为与任何 monad 一起工作而设计的:
lookup :: Ord k => k -> Map k a -> Maybe a
这篇论文过时了还是我遗漏了什么?如果论文实际上已经过时,为什么 lookup
改为仅适用于 Maybe
。
谢谢!
您的教程是 2006 年的。它使用 a very old version of Data.Map
,其中 lookup
的类型确实是:
lookup :: (Monad m, Ord k) => k -> Map k a -> m a
我认为发生这种变化是因为 fail
在 Monad
class 中被广泛认为是一个疣。返回 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
。