Приложение WAI работает с ghci, но не с runhaskell

Я написал простое приложение WAI, которое использует ReaderT, чтобы разрешить доступ к запросу следующим образом:

import qualified Network.Wai as W
handle :: (Resource a) => a -> ReaderT W.Request IO W.Response

где handle — функция, выполняющая основную часть обработки. Затем я вызываю это в своем приложении:

app :: W.Application
app = runReaderT (handle a) -- simplified; i don't think the value of a matters

main :: IO ()
main = run 3000 app

но runhaskell main.hs дает мне следующее:

Couldn't match expected type `Control.Monad.Trans.Resource.ResourceT
                                IO'
            with actual type `IO'
Expected type: ReaderT
                 W.Request (Control.Monad.Trans.Resource.ResourceT IO) W.Response
  Actual type: ServerMonad W.Response
In the return type of a call of `handle'
In the first argument of `runReaderT', namely
  `(handle a)'

что смущает меня по двум причинам:

  1. Я понятия не имею, почему он ожидает этого типа
  2. Звонок resp <- runReaderT (handle a) defaultRequest работает в GHCI!

Почему это происходит?


person hdgarrood    schedule 14.10.2012    source источник


Ответы (1)


Тип Application определяется как:

type Application = Request -> ResourceT IO Response

(Причина ResourceT заключается в том, что вы можете выделять ограниченные ресурсы и использовать их при отправке потокового ответа. Это было бы актуально для отправки ответа на основе большого запроса к базе данных. Но это не имеет прямого отношения к вашему вопросу.)

Ваш runReaderT (reader a) имеет тип Request -> IO Response. Чтобы заставить его вернуть ответ в ResourceT IO, кажется, есть два варианта:

  1. Поднимите его в app: app = lift . runReaderT (reader a). (lift определяется в Control.Monad.Trans.Class.)
  2. Измените тип hanlde на handle :: (Resource a) => a -> ReaderT W.Request (ResourceT IO) W.Response.

Первый подход имеет смысл, если вам когда-нибудь понадобится выполнить операцию, чувствительную к ресурсам, тогда как второй, скорее всего, будет более простым изменением.

person Michael Snoyman    schedule 14.10.2012
comment
Я просматривал старую версию документации Network.Wai — ох! Большое спасибо. - person hdgarrood; 14.10.2012