Подтвердить что ты не робот

Аргумент типа non-variable в ограничении: Ошибка MonadError m

Я определил пользовательский тип ошибки:

data Failure = NetworkError Message |
               UserIsTooStupid Message |
               InvalidOperation Message |
               UnexpectedError Message
type Message = String

Я пытаюсь использовать MonadError с моим типом ошибки:

loadJSON :: (Aeson.FromJSON v, MonadIO m, MonadError Failure m) => URI -> m v
loadJSON uri = do
    body <- liftIO $ getResponseBody =<< simpleHTTP (getRequest uri)
    case Aeson.decode body of
         Just json -> return json
         Nothing -> throwError $ SerialisationError "Couldn't deserialise from JSON"

type URI = String
Другими словами, эта функция может возвращать любую монаду, которая удовлетворяет как MonadIO, так и MonadError, но единственный тип ошибки, которую он может выбросить, - Failure.

Это не скомпилируется с сообщением об ошибке:

Non type-variable argument in the constraint: MonadError Failure m
(Use -XFlexibleContexts to permit this)
In the type signature for `loadJSON':
  loadJSON :: (Aeson.FromJSON v, MonadIO m, MonadError Failure m) =>
              URI -> m v

GHC хочет, чтобы я включил расширение языка FlexibleContexts, чтобы этот код работал. Что делает FlexibleContexts, и действительно ли это необходимо в моем случае? Я предпочитаю не включать языковые расширения волей-неволей, не зная, нужны ли они мне.

Функция компилируется отлично, если я не могу оставить подпись типа, но я не хочу этого делать.

4b9b3361

Ответ 1

Haskell 98 не допускает ограничений, которые выглядят как MonadError Failure m, они должны выглядеть как MonadError a m. Однако возможность иметь такие ограничения была добавлена ​​в GHC, что и делает это расширение. Я понимаю, что опасаюсь языковых расширений, но FlexibleContexts довольно безвреден.

Я полагаю, что в то время, когда вышел Haskell 98, теория типов, использующая такие ограничения, не была разработана, но с тех пор она имеет. Расширение включает дополнительный код в контроле типа, который использует эту теорию. Если вы немного поработаете над Google, вы сможете найти статью о том, как она работает.