Я определил пользовательский тип ошибки, который я хочу использовать с монадой Ошибка. Для примера вот фиктивная:
newtype CustomError = CustomError String
instance Error CustomError where
strMsg = CustomError
Я бы хотел определить функцию throwCustomError
, которая работает как throwError
, но вместо того, чтобы просто выбросить данную строку, она использует ее для создания CustomError
, а затем выдает , которая, Это определение работает:
-- | Throws a 'CustomError' containing the given error message.
throwCustomError msg = throwError $ CustomError msg
Однако я хотел бы добавить объявление типа, главным образом, чтобы Хэддок включил описание функции в сгенерированную документацию. Если я использую :t
в GHCI, это говорит мне, что тип этой функции MonadError CustomError m => String -> m a
, и это имеет смысл для меня, но если я напишу
throwCustomError :: MonadError CustomError m => String -> m a
GHC жалуется на «аргумент не переменного типа» и говорит мне, что я должен использовать -XFlexibleContexts
, чтобы разрешить его. Почему я должен использовать расширение языка для объявления функции этого типа, когда я могу определить функцию этого типа без использования каких-либо языковых расширений? Есть ли способ объявить тип этой функции без использования языковых расширений?
В отдельном примечании я первоначально попытался определить функцию как
throwCustomError = throwError . CustomError
но GHC говорит мне: «Нет экземпляра для (MonadError CustomError m0)
, возникающего в результате использования throwError
». Я не совсем понимаю, почему это определение не эквивалентно другому; насколько я понимаю, они оба означают одно и то же.
Шаг назад: стоит ли мне вообще определять эту функцию? Или я должен просто написать throwError $ strMsg "foo"
, когда я хочу выдать ошибку? (В настоящее время у меня в коде throwError "foo"
, поэтому мне нужно изменить эти строки в любом случае.)