[英]Using the reader monad in snap (or, monad transformers in snap)
Can someone show how to use the snap monad inside the reader monad? 有人可以展示如何在阅读器monad中使用snap monad吗? Monad transformers confuse me.
Monad变形金刚迷惑我。 (Alternatively, I will gladly accept suggestions of tutorials about monad transformers, and ways to see the light and finally grok them.)
(或者,我很乐意接受有关monad变换器的教程的建议,以及查看光线的方法,并最终了解它们。)
Edit: Oops; 编辑:糟糕; forgot to specify what I'm actually trying to do, instead of asking for help with a specific thing.
忘了说明我实际上要做的事情,而不是寻求特定事情的帮助。 Strategy, not tactics.
战略,而不是战术。 I specifically want to share a database connection/pool amongst all handlers, without having to explicitly pass that database connection/pool when specifying routes.
我特别希望在所有处理程序之间共享数据库连接/池,而不必在指定路由时显式传递该数据库连接/池。 It seems that the reader monad would be the way to accomplish that.
似乎读者monad将是实现这一目标的方法。
Snap has ApplicationState type that allows you package whatever application wide resources you need (db connections, template engines etc.) Snap具有ApplicationState类型,允许您打包所需的任何应用程序范围的资源(数据库连接,模板引擎等)
It is located in generated file Application.hs and by default has HeistState and TimerState included into ApplicationState. 它位于生成的文件Application.hs中,默认情况下将HeistState和TimerState包含在ApplicationState中。 You can just put your db connection there and it will be available from anywhere in your Snap application.
您可以将数据库连接放在那里,它可以在Snap应用程序的任何位置使用。
If you're not afraid to use GHC-specific extensions, here's the no-frills approach to monad transformers: 如果你不害怕使用GHC特定的扩展,这里是monad变换器的简单方法:
{-# 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 m r
liftSnap :: Snap a -> MyMonad a
liftSnap act = MyMonad (lift act)
You can now use ask
and local
to access the reader data. 您现在可以使用
ask
和local
来访问阅读器数据。 To run an action in the Snap
monad, you need to "lift" it into your new monad. 要在
Snap
monad中运行一个动作,你需要将它“提升”到你的新monad中。
... r <- liftSnap $ ... snap action ...
You may prefer a shorter name, though. 不过,您可能更喜欢较短的名字。 So, maybe just
snap
. 所以,也许只是
snap
。
Assuming the snap 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. 假设snap monad来自http://hackage.haskell.org/packages/archive/snap-core/0.4.0/doc/html/Snap-Types.html ... Snap是monad(不是monad变换器) ,所以你不能在任意monad中运行它。 You could use the
ReaderT
transformer to embed Reader functionality inside Snap, if that's what you want. 您可以使用
ReaderT
转换器在Snap中嵌入Reader功能,如果这是您想要的。
The type of runSnap
is runSnap
的类型是
runSnap :: Snap a -> (ByteString -> IO ()) -> (Int -> IO ()) -> Request -> Iteratee ByteString IO (Request, Response)
which tells us that it runs in an Iteratee ByteString IO
monad. 它告诉我们它运行在
Iteratee ByteString IO
monad中。 A Reader monad does not let you do IO or iterate over an input stream, so you cannot run a Snap computation in a Reader monad. Reader monad不允许您对输入流执行IO或迭代,因此您无法在Reader monad中运行Snap计算。
If you explain what you want to accomplish, someone may be able to suggest a way to achieve it. 如果你解释你想要完成什么,有人可能会建议一种方法来实现它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.