我最近在使用时遇到错误
threepenny-gui并通过将带有<-
的符号中的模式匹配代码更改为与符号进行模式匹配来解决问题。
在这两种模式匹配形式之间进行更改时,是否有任何理由可以预期行为会发生变化?
具体如下代码:
在IO monad中:
Just events <- Map.lookup elid <$> readMVar sElementEvents
更改为:
mevents <- Map.lookup elid <$> readMVar sElementEvents
let Just events = mevents
以下是修复此问题的提交链接: https://github.com/Davorak/threepenny-gui/commit/fbf6cbe25875fafdc64f7a111ddebf485b45143b
其他平台详情: os:10.8.5 ghc:7.6.3
编辑:添加了发生IO monad的事实
答案 0 :(得分:9)
实际上,是的,他们会产生不同类型的错误。 let
绑定中缺少模式匹配会在评估匹配时引发模式匹配error
,而错过来自(<-)
的模式匹配只调用Monad
实例的{{1}功能
举一个简单的例子,考虑fail
monad where
Maybe
如果我们同时调用它们,我们的行为就会大不相同
instance Monad Maybe where
...
fail _ = Nothing
test1 :: Maybe (Maybe ())
test1 = do
Just a <- return Nothing
return a
test2 :: Maybe (Maybe ())
test2 = do
ma <- return Nothing
let Just a = ma
return a
一般来说,无可辩驳的匹配是一个坏主意,除非你真的确定不可能得到丢失的模式,但如果你必须在> test1
Nothing
> test2
Just *** Exception: PM.hs:23:7-17:
Irrefutable pattern failed for pattern Data.Maybe.Just a
中进行,那么有时无可辩驳的匹配bind比Monad
更好。