2012-10-14 27 views
0

我寫了一個簡單的WAI的應用程序,它採用了ReaderT允許訪問像這樣的要求:WAI應用程序工作ghci的,但不與runhaskell

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中工作!

這是怎麼發生的?

回答

2

類型Application被定義爲:

type Application = Request -> ResourceT IO Response 

(原因ResourceT是讓你可以分配稀缺資源,併發送流媒體響應時使用它們這將是相關的回送基於響應但這與您的問題並不直接相關。)

您的runReaderT (reader a)有類型Request -> IO Response。爲了得到它返回ResourceT IO的反應,似乎有兩種選擇:

  1. 提升它在appapp = lift . runReaderT (reader a)。 (liftControl.Monad.Trans.Class中定義。)
  2. hanlde的類型更改爲handle :: (Resource a) => a -> ReaderT W.Request (ResourceT IO) W.Response

如果您可能需要執行資源敏感的操作,而第二種方法可能更容易,則第一種方法是有意義的。

+0

我在看一箇舊版本的Network.Wai文檔 - 德哦!非常感謝。 – hdgarrood

相關問題