#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
Счастливого Хаскеллинга!