Не удалось вывести (CI.MonadCatchIO (Приложение-обработчик (приложение AuthManager))) в обработчике привязки

#haskell #haskell-snap-framework

Вопрос:

Я использую библиотеку на основе openapi в обработчике; к сожалению, она создает множество сетевых или http-исключений, поэтому я пытаюсь использовать управление.Монада.Кэтчио с этим согласен, но бьюсь головой об эти типы.

Вот где я нахожусь:

 {-# LANGUAGE ScopedTypeVariables #-}

import qualified Control.Exception as E
import qualified Control.Monad.CatchIO as CI (try,MonadCatchIO)
import           Control.Monad.State

import           Snap
import           Application
import           Services
import qualified Helper.Heist as H
import           Snap.AzureAdAuth

-- this is the function that throws the exceptions
runQuery :: (Produces req accept, MimeUnrender accept b1, Show b1, MimeType contentType) => ServicesRequest req contentType b1 accept -> Handler App (AuthManager App) (Either MimeError b1)
runQuery r = ...


runQuery' :: forall req accept contentType b1. (Produces req accept, MimeUnrender accept b1, Show b1, MimeType contentType)
                       => ServicesRequest req contentType b1 accept
                       -> Handler App (AuthManager App) (Either E.SomeException (Either MimeError b1))
runQuery' req = 
  CI.try $ runQuery req :: Handler App (AuthManager App) (Either E.SomeException (Either MimeError b1))

 

Компиляция выдает это сообщение об ошибке:

     * Could not deduce (CI.MonadCatchIO
                          (Handler App (AuthManager App)))
        arising from a use of `CI.try'
      from the context: (Produces req accept, MimeUnrender accept b1,
                         Show b1, MimeType contentType)
        bound by the type signature for:
                   runQuery' :: forall req accept contentType b1.
                                       (Produces req accept, MimeUnrender accept b1, Show b1,
                                        MimeType contentType) =>
                                       ServicesRequest req contentType b1 accept
                                       -> Handler
                                            App
                                            (AuthManager App)
                                            (Either E.SomeException (Either MimeError b1))
        at src/Helper/API.hs:(96,1)-(99,102)
    * In the expression: CI.try $ runQuery req
      In an equation for runQuery':
          runQuery' req = CI.try $ runQuery req

 

Есть какие-нибудь мысли о том, как выстроить типы?

Комментарии:

1. Это внутренние модули или из пакета? вы знаете Handler , откуда он родом? Если это тот, что из Управления. Исключение или Lens , кажется немного странным, возвращать данные из обработчика запроса. Этот вопрос крайне нуждается в большем контексте того, что вы используете, что вы пытаетесь сделать и как вы пришли к тому, что у вас есть в настоящее время.

2. Одно я могу вам сказать: если это Handler не монада, try то это неправильная функция. Вот в чем смысл сообщения об ошибке: MonadCatchIO для этого типа нет экземпляра Handler App (AuthManager App) .

3. Привет @Ari, это обработчик, определенный в фреймворке Snap , это определенно монада.

Ответ №1:

Я не могу точно воспроизвести ваш пример, потому что все еще существует много типов, для которых я не знаю, откуда они берутся.

Монада фреймворка Snap Handler используется MonadBaseControl для встраивания IO монады, а не в более традиционном стиле mtl MonadIO , MonadCatchIO который MonadCatchIO-mtl используется.

Вместо lifted-base этого пакет предоставляет примитивы, такие как try (in Control.Exception.Lifted ) для этих вложений.

Следующий код компилируется для меня:

 import Snap.Snaplet
import Control.Exception.Lifted hiding (Handler)

runQuery :: Handler a b c
runQuery = undefined

runQuery' :: (Exception e) => Handler a b (Either e a1)
runQuery' = try runQuery
 

Счастливого Хаскеллинга!