Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell和-XDeriveDataTypeable中引发异常_Haskell - Fatal编程技术网

在Haskell和-XDeriveDataTypeable中引发异常

在Haskell和-XDeriveDataTypeable中引发异常,haskell,Haskell,正在尝试在Haskell中引发异常: 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

正在尝试在Haskell中引发异常:

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'
我怎么能修好它


你能不能也写下调用测试函数时如何捕获这种异常?

在命令行中传入
-XDeriveDataTypeable
,或者将

{-# LANGUAGE DeriveDataTypeable #-}

在文件的顶部。这两种方法中的任何一种都指定GHC派生数据实例和可类型实例所需的语言扩展。我更喜欢第二种方法,因为它将扩展的范围限制在需要它的文件上。

出现此错误是因为您试图为数据类型派生可类型类的实例(使用
派生(Show,Typeable)
;异常类型需要可类型实例),但这在标准哈斯克尔是不可能的;您需要一个GHC扩展来完成此操作

您可以手动编写一个可键入实例,但使用
DeriveDataTypeable
实际上是推荐的方法。要启用扩展,您可以放置:

{-# LANGUAGE DeriveDataTypeable #-}
在源文件的顶部。在命令行上传递
-XDeriveDataTypeable
也可以,但不建议这样做;最好在文件顶部记录您使用的语言扩展名,这也简化了编译,因为您不必记住标志。(它还隔离了需要它们的文件的扩展名。)

此外,在
test
的定义中,应将
throw
替换为
throwIO
,就像在IO单子中一样

您还应该添加

import Prelude hiding (catch)
在您的导入之上,因为Prelude的
catch
用于旧的异常处理机制,否则,当您尝试捕获异常时,该机制将与Control.exception冲突

捕获异常很简单;您只需使用:

示例::IO() 示例=do 结果>退出失败 处理程序ThatException=putStrLn“Yikes!”>>exitFailure (
foo`catch`bar
语法与
catch foo bar
相同;它适用于任何函数。)


请注意,异常处理程序必须与正在运行的操作具有相同的返回类型;通过将异常传递给
throwIO
,您可以
返回一个合适的
CellPos
,使异常冒泡到下一个处理程序(可能是全局异常处理程序,它只是打印异常并停止程序),或者以其他方式从程序中退出,如本例所示。

谢谢!你能不能也写下我在调用测试函数时如何捕捉这种异常?
example :: IO ()
example = do
  result <- test "hello" `catch` handler
  ...
  where handler ThisException = putStrLn "Oh no!" >> exitFailure
        handler ThatException = putStrLn "Yikes!" >> exitFailure