8

最近、 threepenny-gui の使用中にエラーが発生しまし た。コードを do 表記のパターン マッチから<-let 表記のパターン マッチに変更することで解決しました。

これら 2 つの形式のパターン マッチングを変更するときに動作の変更を予期する必要がある理由はありますか?

具体的には、次のコード:

IO モナドでは:

Just events <- Map.lookup elid <$> readMVar sElementEvents

に変更されました:

mevents <- Map.lookup elid <$> readMVar sElementEvents
let Just events = mevents

これは私のために問題を修正したコミットへのリンクです :

追加のプラットフォームの詳細: os: 10.8.5 ghc: 7.6.3

編集:これがIOモナドで起こっているという事実を追加しました

4

1 に答える 1

11

実際、そうです、それらはさまざまな種類のエラーを生成します。letバインディングでパターン マッチが見つからない場合、errorそのマッチが評価されるたびにパターン マッチが発生し、インスタンスの関数(<-)を呼び出すだけでパターン マッチが見つからないMonadfail

簡単な例として、次の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

Monad一般に、欠落しているパターンを取得することが不可能であることが本当に確実でない限り、反駁不可能なマッチングは悪い考えですが、 でそれを行う必要がある場合はバインドでの反駁不可能なマッチングが a よりも優れていることがありletます。

于 2013-11-17T03:21:03.817 に答える