# 119: List comprehension における Fail がランタイムエラーになる [↑up](bunny_notes) - issued: 2020-12-13 - 分類: A サンプルコードが fail - status: Closed (2020-12-13) ## 概要 Prelude.hs を書いているなかで発見した件。 List comprehension においてパターンマッチが fail したときに、ランタイムエラーとなってしまう。 例えば、次のようなプログラム: $$
{ xs = [Just 3, Just 2, Nothing, Just 9, Nothing, Nothing, Just 8] main = print $ sum $ [y | Just x <- xs, let y = x * 2] $$} これをコンパイル、実行しようとするとランタイムエラーとなる。 $${ $ bunny testrun listcomprihension.hs /home/unno/bunny/0.9.0/bin/bunnyc -d ./jout/listcomprihension --xno-implicit-prelude /home/unno/bunny/0.9.0/lib/Prelude.hs /home/unno/bunny/0.9.0/bin/bunnyc -d ./jout/listcomprihension --xlibrary-path /home/unno/bunny/0.9.0/lib listcomprihension.hs Error: Non-exhaustive patterns. $$} ## 調査ログ ## 2020-12-13 そういえば、こころあたりがあった。 The Haskell 2010 language report の [3.11 List Comprehensions](https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11) では、${[e | p <- l, Q]} の翻訳は次のように書かれている: $$ { [e | p <- l, Q] = let ok p = [e | Q] ok _ = [] in concatMap ok l $$} だが、私は当時、ok p が常にマッチするようにみえてしまい(${p} に任意のパターンが来うるので fail する可能性があるのだが、p が普通の引数に見えて勘違いした)、 以下のように実装してしまっていたのだった。 $$ { [e | p <- l, Q] = let ok p = [e | Q] in concatMap ok l $$} というわけで、理由は簡単だった。仕様通りに直して解決。 概要のところに挙げたプログラムを test/sample323.hs とする。