gpt4 book ai didi

haskell - 在 Haskell 和 -XDeriveDataTypeable 中引发异常

转载 作者:行者123 更新时间:2023-12-02 14:17:38 26 4
gpt4 key购买 nike

尝试在 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'

我该如何解决这个问题?

您还可以写一下我如何在调用测试函数时捕获此类异常吗?

最佳答案

您收到此错误是因为您尝试为您的数据类型派生 Typeable 类的实例(使用 deriving (Show, Typeable);异常需要 Typeable 实例类型),但这在标准 Haskell 中是不可能的;你需要一个 GHC 扩展才能做到这一点。

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

{-# LANGUAGE DeriveDataTypeable #-}

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

此外,您应该在 test 的定义中将 throw 替换为 throwIO,因为它 guarantees the correct ordering在 IO 单子(monad)中。

您还应该添加

import Prelude hiding (catch)

在您的导入之上,因为 Prelude 的 catch 用于较旧的异常处理机制,否则当您 try catch 异常时,该机制会与 Control.Exception 发生冲突。

捕获异常很简单;你只需使用 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 相同;它适用于任何函数。)

请注意,您的异常处理程序必须具有与您正在运行的操作相同的返回类型;您可以返回一个适当的CellPos,通过传递它使异常冒泡到下一个处理程序(可能是全局异常处理程序,它只是打印异常并停止程序)到 throwIO,或者以其他方式逃离程序,例如 System.Exit.exitFailure在这个例子中。

关于haskell - 在 Haskell 和 -XDeriveDataTypeable 中引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8853896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com