# 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 とする。