2012-04-01 10 views
3

Ich bin ein Happstack Server zu schreiben und ich habe eine MongoDB-Datenbank zu verbinden. Dafür habe ich eine Funktion, um eine Verbindung PoolErweiterung des ServerPartT Monad mit einem Reader

type MongoPool = Pool IOError Pipe 

withMongo :: (MongoPool -> IO a) -> IO() 
withMongo f = do 
    pool <- dbPool 
    f pool 
    killAll pool 

Und dann eine Funktion erstellen eine Action mit einem erstellten Pool auszuführen:

runDB :: (MonadIO m) => MongoPool -> Action IO a -> m (Either Failure a) 
runDB pool f = liftIO $ do 
    pipe <- runIOE $ aResource pool 
    access pipe master dbName f 

Es ist offensichtlich, dies erfordert die pool in allen tragen Routen als Parameter. Ich möchte es in ein ReaderT wickeln, so dass runDB einen Typen wie Action IO a -> ServerPart (Either Failure a) haben oder noch besser, Action IO a -> ServerPart a, in denen ein Fehler in einem HTTP-Fehler 500 automatisch zur Folge haben wird.

Ich habe ein Problem Einwickeln meinen Kopf herum, wie das erreicht werden kann, und ich würde für einige Hinweise von Menschen lieben, die mehr Erfahrung mit Haskell Monaden und happstack haben.

Danke.

Antwort

3

Durch diese Frage habe ich eine andere mit einem sehr guten Hinweis gefunden, und ich habe diese gebaut. Es scheint gut zu funktionieren und ich dachte, ich würde es teilen:

type MongoPool = Pool IOError Pipe 

type DBServerPart a = ReaderT MongoPool (ServerPartT IO) a 

hostName = "127.0.0.1" 

dbName = "test" 

defaultPoolSize = 10 

runDB :: Action IO a -> DBServerPart (Either Failure a) 
runDB f = do 
    pool <- ask 
    liftIO $ do 
     pipe <- runIOE $ aResource pool 
     access pipe master dbName f 

withMongo :: DBServerPart a -> ServerPart a 
withMongo f = do 
    pool <- liftIO $ dbPool 
    a <- runReaderT f pool 
    liftIO $ killAll pool 
    return a 

dbPool = newPool fac defaultPoolSize 
    where fac = Factory { 
      newResource = connect $ host hostName, 
      killResource = close, 
      isExpired = isClosed 
     } 
+0

Das sieht für mich richtig aus. Die andere Option ist, 'Typ DBServerPart a = ServerPartT (ReaderT MongoPool IO) a' zu tun, und dann' mapServerPartT' verwenden abzuflachen es 'ServerPartT IO'. Das ist ein kleiner Unterschied zwischen zwei Lösungen. Mit dieser Methode können Sie die 'XMLGenerator'-Instanz für' ServerPartT' nutzen, wenn Sie 'HSX' verwenden. Meistens ist es egal, wie du es tust. – stepcut