haskell - 如何判断包装在 SomeException 中的异常是否是类的实例?
问题描述
我想为自定义异常类型实现一个类实例,然后在该类型的处理程序中使用该类实例。下面的代码显示了我正在尝试做的事情;我想找到适合“???”的东西。
这是棘手的部分:我想在不引用MyException
handler 的情况下执行此操作。例如,使用fromException
orData.Typeable.cast
将不起作用。原因是处理程序将存在于一个包中,而异常类型将存在于另一个包中。我希望能够编写额外的包来定义它们自己的异常类型和MyClass
实例,并且我希望处理程序能够在不知道异常类型是什么的情况下使用这些包。
我知道有很多关于“判断 X 是否是 Y 的实例的方法”的问题,但我无法在SomeException
包装器存在的情况下找到一个工作。(例如:https://wiki.haskell.org/GHC/AdvancedOverlap。)
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Control.Exception
data MyException = MyException
deriving Show
instance Exception MyException
class MyClass a where
useMyClass :: a -> String
main :: IO ()
main = catch (throwIO MyException) $ \(SomeException e) -> do
if ??? then (putStrLn ("Used custom exception class: " <> useMyClass e))
else (putStrLn ("Showing exception: " <> show e))
解决方案
做不到。但是,您可以使开放包装器存在:
data SomeMyClass where SomeMyClass :: MyClass a => a -> SomeMyClass
然后,您可以要求所有用户抛出 a而不是他们的自定义类型,如有必要SomeMyClass
,首先通过调用构造函数进行转换。SomeMyClass
catches (throwIO (SomeMyClass MyException))
[ Handler (\(SomeMyClass e) -> putStrLn ("used custom exception: " <> useMyClass e))
, Handler (\(SomeException e) -> putStrLn ("showing exception: " <> show e))
]
推荐阅读
- c# - 锁定以追加到 ASP.NET 中的文件
- asp.net - 无法从 Nuget 包管理器在 Asp.net MVC 4.5 版本中添加包 Microsoft.Owin.Host.SystemWeb
- symfony - 如何从第三个捆绑包中覆盖第三个捆绑包的配置
- django - 使用虚幻数据自动填充 Django 模型数据库表
- css - 渲染错误还是我的错误?:从 Flexbox 伸出的溢出隐藏零高度
- amazon-lex - 将解析的意图和槽从 Amazon-Lex 发送回客户端
- visual-studio - Xamarin 表单与 Visual Studio 2017
- java - 中断等待过程android
- android - 日历提醒不适用于 OnePlus 设备
- javascript - AngularJs ng-repeat 跟踪 $index 问题与 angular-bootstrap-switch