let n = case args of [] -> 30 [x] -> read x otherwise -> error "Invalid Program Option"
って何気なく書いてたけど,これ,よく考えるとおかしいです.
僕としては,ガードを使って
let x = case n of n | n < 0 = "negative" | otherwise = "not negative"
って書いてるつもりで otherwise
を使ってたのですが,
最初のコードだと, otherwise
はガードじゃなくてパターン部分に書かれてるよね.
otherwise
パターンなんて物は存在しない筈なのに,なんでこれ,コンパイル通るんでしょうか?
結論をいってしまうと,これは単に, otherwise
という変数に値を束縛しているだけです.
具体的に例を挙げて説明すると,
let n = case args of [] -> 30 [x] -> read x otherwise -> error $ show otherwise
上の case
式における show otherwise
の otherwise
は,
Prelude.otherwise
ではなく args
の中身が束縛される変数なので,
args
として(例えば) ["1", "2"]
を渡すと,
show otherwise
は "True"
ではなく "[\"1\",\"2\"]"
になります.
もちろん,本来なら,これは
let n = case args of [] -> 30 [x] -> read x _ -> error "Invalid Program Option"
と書くべきです.
コンパイルエラーにならず,(結果的には)意図した通りの動作になるとはいえ,
パターンマッチ内のガードで Prelude.otherwise
を使おうとした場合には,事故る可能性があるので.
後で書き直す.