2012-01-27 28 views
13

Estoy jugando con la escritura de una aplicación web. En este caso, estoy usando scotty y redis, pero este problema aparece en cualquier combo web/db. Utilicé happstack antes de esto, así que me encantaría un ejemplo allí también.¿Se combinan dos mónadas cuando ninguno tiene un transformador?

Scotty tiene que definir rutas en una mónada anidada, lo que hace que sea fácil para acceder a la conexión de base dentro de una ruta:

main = do 
    db <- connect defaultConnectInfo 
    scotty 3000 $ do 

    get "/keys" $ do 
     keys <- liftIO $ runRedis db $ keys "*" 
     html $ T.pack $ show keys 

la DO bloque en get tiene tipo: Web.Scotty.ActionM(). Todos los comandos redis tienen el tipo Database.Redis.Redis a. Ni redis ni scotty tienen un transformador de mónada.

¿Cuál es la mejor manera de combinar esto? Soy nuevo en Haskell, pero logré que ReaderT trabajara con la mónada web en happstack.

Idealmente, podría de alguna manera crear una nueva pila de mónada que admita tanto keys como html en el mismo bloque do.

+1

¿La gente normalmente solo se conforma con liftIO en los frameworks web de haskell? –

+1

No sé una respuesta aquí, pero me imagino que su problema es similar a los transformadores de mónada. Básicamente, desea implementar un tipo, llamémoslo 'IdentityTT m' ma', de modo que 'IdentityTT m'' se comporte exactamente como [' IdentityT'] (http://hackage.haskell.org/packages/archive/transformers /0.2.1.0/doc/html/Control-Monad-Trans-Identity.html). La primera pregunta que debe responderse, por supuesto, es si eso es posible. –

+0

Otra forma de formular la pregunta es: ¿usa liftIO para consultar una base de datos en todos los frameworks haskell? ¿Cuál es el patrón más común cuando la base de datos no está integrada en el marco? –

Respuesta

4

Por alguna razón, sentí que LiftIO era feo, pero no está nada mal. Especialmente si usted hace esto:

queryRedis :: Connection -> Redis a -> ActionM a 
queryRedis db r = liftIO $ runRedis db r 

y definir una función parcialmente aplicada redis = queryRedis db. Gracias a todos

Cuestiones relacionadas