我有一种情况,我使用的大多数操作都是部分函数。我希望函数的返回类型根据上下文而变化,这应该确定发生的异常处理类型以及报告的错误类型。我目前的解决方案是定义一个由错误类型参数化的函数,然后使用类型类将操作实现为开放函数。例如,下面是head的一个实现,假设在单元类型方面对Maybe有一个合适的Error和MonadError实现:
class (Error e, MonadError e m) => Head m e | m -> e where
head :: [a] -> m a
errorHead :: (Error e, MonadError e m) => e -> [a] -> m a
errorHead e [] = throwError e
errorHead e (x : xs) = return x
instance Head Maybe () where
head = errorHead ()
instance Head (Either String) String where
head = errorHead "error: empty list"
这种实现的优点是可以根据调用head的上下文抛出不同的错误。我的问题是这是否可以在不使用辅助操作和开放函数定义函数的情况下完成。如果不是,第二个问题是这个解决方案是否是最优的。特别是,有没有更好的方法来实现这种行为?