4249


Snappy パッケージの下記
[decompress](https://hackage.haskell.org/package/snappy-0.2.0.2/docs/src/Codec-
Compression-Snappy-Lazy.html) を利用する際、どのようにコーディングを行えば例外処理が出来るでしょうか？

[code]

    decompress :: ByteString -> ByteString
    
    Decompress data in the Snappy format.
    If the input is not compressed or is corrupt, an exception will be thrown.
    
[/code]

`try` を利用した場合 Left になると思ったのですが、結果は Right となってします。

[code]

    ghci> import Data.ByteString
    ghci> import Control.Exception
    ghci> import Codec.Compression.Snappy
    ghci> let bs = "test" :: ByteString
    ghci> decompress bs
    "*** Exception: user error (Codec.Compression.Snappy.decompress: corrupt input )
    ghci> try (return $ decompress bs)::IO (Either SomeException ByteString)
    Right "*** Exception: user error (Codec.Compression.Snappy.decompress: corrupt input )
    
[/code]


CC BY-SA 3.0
2015-01-07T08:28:54.380
4238
2015-01-15T08:30:28.547
2015-01-15T08:30:28.547
570
570
question
haskell exception
Haskell Snappy パッケージの decompress を利用した場合の例外処理について


この挙動はsnappyライブラリとは直接関係なく、Haskellの評価戦略によるものです。

[code]

    λ:2> import Control.Exception
    λ:3> try (return undefined) :: IO (Either SomeException ())
    Right *** Exception: Prelude.undefined
    
[/code]

`return`は引数の評価を強制しないので`try (return undefined)`の`undefined`は評価されることなく`Right
undefined`となり、GHCiが`Right`まで出力した後、初めて中身が評価され例外が上がります。これを防ぐには`Control.Exception.evaluate`で評価を強制すればよいのです。

[code]

    λ:4> try (evaluate undefined) :: IO (Either SomeException ())
    Left Prelude.undefined
    
[/code]

全く同じ内容がReal World
Haskellの19章でも[取り上げられています](http://book.realworldhaskell.org/read/error-
handling.html#errors.exceptions.lazy)。


CC BY-SA 3.0
2015-01-07T13:48:13.400
4249
2015-01-07T13:48:13.400
6121
4238
answer