Search code examples
haskellhaskell-snap-framework

How do you make a Snaplet like HasHdbc work outside the Snap context?


In the tutorial for using the HDBC Snaplet, it says that "One of the goals when designing the HDBC snaplet was to separate the functions from the Handler monad, or any Snap-related monad, so that the same queries could also be run outside of a Snap context, for example in a command-line tool."

I'm trying to accomplish just this.

The typeclass HasHdbc has the definition

class  (  IConnection c
       ,  ConnSrc s
       ,  MonadCatchIO m
       )
  =>   HasHdbc m c s | m -> c s where
  getHdbcState :: m (HdbcSnaplet c s)

One would define an instance of this typeclass of Snap app this way:

instance HasHdbc (Handler App App) Connection IO where
  getHdbcState = with dbLens get

Can someone sketch how one would make this command line tool outside the Snap context, using the HasHdbc typeclass? I understand typeclasses on a basic level, but the type signature getHdbcState :: m (HdbcSnaplet c s) is a bit of a challenge for me define an instance of for, say, the IO Monad.


Solution

  • You're on the right track. You do need to define a HasHdbc instance for whatever monad you want to use. To do that, you have to define a function getHdbcState that returns an HdbcSnaplet. The information that goes in that data type can't come from nowhere, but the getHdbcState function doesn't take any arguments. That means that you'll either have to put in constants for your database server or read them from a file or something. A more flexible approach would be to make a HasHdbc instance for ReaderT or Reader.