I am using the LevelDB library and Snap framework together. I have:
main :: IO ()
main = runResourceT $ do
db <- open "thedb" defaultOptions { createIfMissing = True }
liftIO $ serveSnaplet defaultConfig $ initWeb db
Now in my handler, I'm unsure how to get back to MonadResource IO
in order to query the database:
handleWords :: Handler App App ()
handleWords = do
words <- uses thedb $ \db -> $ get db def "words"
writeBS $ pack $ show words
Which gives me a: No instance for (MonadResource IO) arising from a use of 'get'
Any ideas? I feel like I'm missing something about how to properly create a monad "stack". Thanks
MonadResource
/ResourceT
is one way of acquiring scarce resources in a way that guarantees resources will be freed in the case of an exception. Another approach is the bracket
pattern, which is supported by Snap via the bracketSnap
function. You can use this to create the ResourceT
context needed by LevelDB:
import qualified Control.Monad.Trans.Resource as Res
bracketSnap Res.createInternalState Res.closeInternalState $ \resState -> do
let openAction = open "thedb" defaultOptions { createIfMissing = True }
db <- Res.runInternalState openAction resState
This could be made simpler with some changes in Snap and leveldb:
open
function, which presumes a MonadResource
context, there could be a function which returns a Resource
value. I'm making this tweak in persistent for the 2.0 release.MonadResource
or the Resource
monad (two separate concepts with unfortunately similar names).