2011-02-06 64 views
4

有人可以演示如何在讀卡器monad內使用快照monad? Monad變形金剛迷惑了我。 (或者,我會很樂意接受關於monad變形金剛教程的建議,以及如何看清燈光並最終得到它們。)在快照中使用讀卡器monad(或者,在快照中使用monad變壓器)

編輯:糟糕;忘了指定我實際想要做的事情,而不是尋求具體的幫助。策略,而不是戰術。我特別希望在所有處理程序之間共享數據庫連接/池,而不必在指定路由時顯式傳遞該數據庫連接/池。看來,讀者monad將成爲實現這一目標的途徑。

回答

5

捕捉具有ApplicationState類型,可以讓你打包任何你需要的應用程序範圍內的資源(數據庫連接,模板引擎等)

它位於生成的文件Application.hs,默認情況下有HeistState和TimerState納入ApplicationState 。你可以把你的數據庫連接放在那裏,它可以在Snap應用程序的任何地方使用。

0

假設捕捉monad是從http://hackage.haskell.org/packages/archive/snap-core/0.4.0/doc/html/Snap-Types.html ...捕捉是一個monad(不是一個monad變換器),所以你不能在任意monad內運行它。如果這是您想要的,您可以使用ReaderT轉換器在Snap內嵌入Reader功能。

類型的runSnap

runSnap :: Snap a -> (ByteString -> IO()) -> (Int -> IO()) -> Request -> Iteratee ByteString IO (Request, Response) 

這告訴我們,在Iteratee ByteString IO單子上運行。 Reader monad不允許您執行IO或迭代輸入流,因此您無法在Reader monad中運行Snap計算。

如果你解釋你想完成什麼,有人可能會提出一種方法來實現它。

+0

經過更新以反映我之後的真實情況,對此感到遺憾。 – tehgeekmeister 2011-02-07 00:47:57

4

如果你不害怕使用GHC特定的擴展,這裏是沒有廉價的方法來單子變壓器:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

import Control.Monad.Reader 

data ReaderData = ... 

newtype MyMonad a = MyMonad (ReaderT ReaderData Snap a) 
    deriving (Monad, MonadReader ReaderData) 

runMyMonad :: MyMonad a -> ReaderData -> Snap a 
runMyMonad (MyMonad m) r = runReaderT m r 

liftSnap :: Snap a -> MyMonad a 
liftSnap act = MyMonad (lift act) 

您現在可以使用asklocal訪問讀取器數據。要在Snap monad中運行一個操作,您需要將它「提升」到新的monad中。

... r <- liftSnap $ ... snap action ... 

雖然您可能更喜歡較短的名稱。所以,也許只是snap

+0

你甚至不需要`newtype`,這可能只是一個類型的同義詞:`type MyMonad = ReaderT ReaderData Snap`。然後使用標準的`lift :: Snap a - > MyMonad a`。 – luqui 2011-02-07 01:24:46

+0

ReaderData這裏只是我想要的讀者類型,我假設? – tehgeekmeister 2011-02-07 01:59:50