符号与let中的模式匹配

时间:2013-11-17 02:51:12

标签: haskell pattern-matching do-notation threepenny-gui

我最近在使用时遇到错误 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的事实

1 个答案:

答案 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更好。