私が使用している操作の大部分が部分関数であるという状況があります。発生する例外処理の種類と報告されるエラーの種類を決定するコンテキストに応じて、関数の戻りの種類を変えたいと思います。私の現在の解決策は、エラータイプによってパラメーター化された関数を定義し、タイプクラスを使用してオープン関数として操作を実装することです。たとえば、以下はheadの実装であり、ユニットタイプの観点から多分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が呼び出されるコンテキストに応じて異なるエラーがスローされる可能性があることです。私が持っている質問は、補助操作とオープン関数を使用して関数を定義せずにこれを達成できるかどうかです。そうでない場合、2番目の質問は、このソリューションが最適であるかどうかです。特に、この動作を実現するためのより良い方法はありますか?