にゃあさんの戯言日記

2007-12-17

do内のletがパターンマッチに失敗した例外をキャッチする方法?

こんなコードではまってた。

import Control.Exception
main = try doIO >>= print
doIO = do [x] <- return $ [1, 2]
          return x
-- Left user error (Pattern match failure in do expression at c:/home/tmp/hoge.hs:3:10-12)
import Control.Exception
main = try doIO >>= print
doIO = do let [x] = [1, 2]
          return x
-- Right *** Exception: c:/home/tmp/hoge.hs:3:14-25: Irrefutable pattern failed for pattern [x]

後者の例外をキャッチするのはどうすればいいんだろう... ええっと、doの中のletってどんなsyntax sugarだっけ?

do内のletがパターンマッチに失敗した例外をキャッチする方法?(2)

Gusさん、コメントありがとうございます。

まだあまり整理がついていないのだけど、コメントを見る限りでは、let式のパターンマッチが遅延しているために、tryの外に出てから例外が投げられてしまうためにキャッチできていないように見える。前者の例はdo式の書き換え規則から分かるとおり、クロージャとcase相当のパターンマッチに書き換えられるので遅延しない、と。

関数的なところで例外なんて投げるもんじゃないですね。

GusGus 2007/12/18 00:26 from http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf
p. 121 (or 131 of pdf)
1. do {e} → e
2. do {e; es} → e >> do {es}
3. do {let decls; es} → let decls in do {es}
4. do {p <- e; es}→let ok p = do {es} ; ok = fail ”...” in e >>= ok

どう捕まえればよいのでしょう...

GusGus 2007/12/18 00:37 return x を seq x $ return x にするとつかまりました。xの評価が遅延しているのでしょうか。

次ににゃあさんは、「遅延と例外キャッチの関係を具体的に示してください」と、言う!

nyaasannyaasan 2007/12/18 01:22 しばらくはそのネタでいじられそうな気がします。w

Connection: close