Haskellのerror関数が型破りなんだが型破ってない。

Thu Jun 13 22:52:36 JST 2013 (modified: Fri Sep 29 21:38:45 JST 2017)
views: 2424, keywords:プログラミング,Haskell,Haskell中毒 この記事は最終更新日が7年以上前のものです。

Haskellでコマンドを書いていて、エラーの出し方がよく分からないのでゴマカシゴマカシしていたのですが、真面目にオライリーの本を読んでるとerrorという関数を見つけました。ちゃんと例外処理をやるにはモナド使えとかなんとか書いてありましたが、コマンドならこれが一番いいかと。

例えば、標準入力から文字列を読んで最初の単語だけ出力するプログラムを書きます。

uedamac:~ ueda$ cat hoge.hs
   import System.IO
   
   main :: IO ()
   main = getContents >>= putStrLn . firstWord
   
   firstWord :: String -> String
   firstWord cs = head $ words cs

こいつをコンパイルして実行すると実行できる訳ですが、単語を入力しないという意地悪をするとエラーが発生します。

uedamac:~ ueda$ ghc hoge.hs
   [1 of 1] Compiling Main ( hoge.hs, hoge.o )
   Linking hoge ...
   uedamac:~ ueda$ echo This is a pen. | ./hoge
   This
   uedamac:~ ueda$ echo | ./hoge
   hoge: Prelude.head: empty list
   uedamac:~ ueda$ echo $?
   1

そんな意地悪な入力にはちゃんと教育的指導を与えなければいけません。error関数を使うとちゃんと自分でエラーメッセージを作文できます。

uedamac:~ ueda$ cat hoge2.hs 
   import System.IO
   
   main :: IO ()
   main = getContents >>= putStrLn . firstWord
   
   firstWord :: String -> String
   firstWord cs = if (length $ words cs) == 0
    then error "no words"
    else head $ words cs

はい実行。

uedamac:~ ueda$ ghc hoge2.hs
   [1 of 1] Compiling Main ( hoge2.hs, hoge2.o )
   Linking hoge2 ...
   uedamac:~ ueda$ echo This is a pen. | ./hoge2
   This
   uedamac:~ ueda$ echo | ./hoge2
   hoge2: no words
   uedamac:~ ueda$ echo $?
   1

終了ステータスは1で固定なんでしょうか?まあ、今の時点ではよいでしょう。

んで、このerror関数を使うなとかなんだとかいろいろ議論はあるんですが、面白いのは型で、こんな定義になってます。

error :: [Char] -> a

出力が任意の型(a)になってるので、型のチェックに通るワケですね・・・。しかし、ずるいことにa型を返すと言いつつこいつは何も返しません。この関数が呼ばれると、他の処理を全部破棄して何も恐れるものの無い状態にしてからエラーを吐くだけなので、処理上、特に問題ないようです。

これ考えた人、これ考えたときどんな顔してたんでしょうね?

いろいろ興味が尽きませんが、寝るです。

ノート   このエントリーをはてなブックマークに追加 
 

prev:HaskellでStringを使う場合とByteStringを使う場合の速度比較 next:第三者機関というのは

やり散らかし一覧

記事いろいろ