Using a monad reader in a snap (or, monad transformers in a snap)

Can someone show how to use the tethered monad inside the reader monad? Monad Transformers confuse me. (As an alternative, I gladly accept the tutorial tutorials on monad transformers, as well as ways to see the light and finally pull them out.)

Edit: Oops; I forgot to indicate what I'm actually trying to do, instead of asking for help with a particular thing. Strategy, not tactics. I specifically want to share the database connection / pool among all handlers, without the need to explicitly transfer this database connection / pool when specifying routes. It seems that a reader monad will be a way to achieve this.

+4
source share
3 answers

Snap is of type ApplicationState, which allows you to pack any application resources available to you (db connections, template engines, etc.).

It is located in the generated Application.hs file and by default contains the HeistState and TimerState included in the ApplicationState. You can simply host your db connection and it will be available from anywhere in your Snap app.

+5
source

If you are not afraid to use GHC-specific extensions, then there is no unnecessary approach to monad transformers:

{-# 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 mr liftSnap :: Snap a -> MyMonad a liftSnap act = MyMonad (lift act) 

Now you can use ask and local to access the reader data. To trigger an action in the Snap monad, you need to β€œraise” it into your new monad.

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

However, you may prefer a shorter name. So maybe just a Snap .

+4
source

Assuming the linked monad is from http://hackage.haskell.org/packages/archive/snap-core/0.4.0/doc/html/Snap-Types.html ... Snap is a monad (not a monad transformer) , so you cannot run it inside an arbitrary monad. You can use a ReaderT transformer to embed Reader functions inside Snap if you need it.

Type runSnap -

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

who tells us that he works in the Iteratee ByteString IO monad. Modifying Reader does not allow IO or iterating over the input stream, so you cannot run Snap calculation in the Reader monad.

If you explain what you want to achieve, someone can suggest a way to achieve it.

0
source

Source: https://habr.com/ru/post/1338655/


All Articles