2012-01-13 17 views
2

ハスケルで投げる例外と-XDeriveDataTypeable

import Control.Exception 
import Data.Typeable 

data MyException = ThisException | ThatException deriving (Show, Typeable) 
instance Exception MyException 

data CellPos = CellPos Int Int deriving (Show, Read) 

test :: String -> IO CellPos 
test str = do 
{ 
if length str == 0 
then 
    throw ThisException; 
else 
    return (CellPos 0 0); 
} 

コンパイラは言う:

Can't make a derived instance of `Typeable MyException': 
    You need -XDeriveDataTypeable to derive an instance for this class 
In the data type declaration for `MyException' 

私はそれを解決することができますか?

test関数を呼び出すときに、どのようにそのような例外をキャッチすることができますか?

答えて

12

データ型のTypeableクラスのインスタンスを派生させようとしているため(deriving (Show, Typeable);例外タイプに対してTypeableインスタンスが必要です)、このエラーが発生していますが、これは標準では不可能ですハスケル;それを行うにはGHC拡張が必要です。

タイプ可能インスタンスを手動で記述することができますが、実際にはDeriveDataTypeableを使用してこれを行うことをお勧めします。拡張機能を有効にするには、次のように入力します。

{-# LANGUAGE DeriveDataTypeable #-} 

ソースファイルの上部に配置します。コマンドラインに-XDeriveDataTypeableを渡すこともできますが、お勧めできません。ファイルの先頭で使用する言語拡張を文書化するのが最善です。また、フラグを覚える必要がないため、コンパイルも簡単です。 (それはまたそれらを必要とするファイルへの拡張を分離します。)また

、あなたはそれIOモナドでguarantees the correct orderingとして、testの定義にthrowIOthrowを置き換える必要があります。プレリュードのcatchは、あなたがしようとすると、例外をキャッチしたときにそうControl.Exceptionと衝突う古い例外処理メカニズムのためにあるよう

また、あなたの輸入上記

import Prelude hiding (catch) 

を追加する必要があります。

例外をキャッチするのは簡単です。あなただけcatchを使用します。

example :: IO() 
example = do 
    result <- test "hello" `catch` handler 
    ... 
    where handler ThisException = putStrLn "Oh no!" >> exitFailure 
     handler ThatException = putStrLn "Yikes!" >> exitFailure 

foo `catch` bar構文はcatch foo barと同じであり、それは任意の関数のために動作します。)

注例外ハンドラは、あなた」アクションと同じ戻り値の型を有していなければならないこと再実行中。 returnを適切なCellPosとすると、次のハンドラ(おそらく、例外を出力してプログラムを停止するグローバル例外ハンドラ)に例外バブルを適用してthrowIOに渡すか、または他の方法でプログラムからエスケープしますこの例ではSystem.Exit.exitFailureです。

+0

ありがとう、あなた!また、テスト関数を呼び出すときにそのような例外をどのように捕らえることができますか? – user606521

+0

@ user606521:確か;私は例で私の答えを更新しました。 – ehird

4

コマンドラインで-XDeriveDataTypeableに渡すか、ファイルの先頭に

{-# LANGUAGE DeriveDataTypeable #-} 

ラインを入れてどちらか。どちらのメソッドでも、GHCがDataおよびTypeableのインスタンスを派生させるために必要な言語拡張を指定します。私は、拡張の範囲を必要なファイルに限定するので、2番目の方法が好まれます。

関連する問題