使用快照中的阅读器monad(或快照中的monad变换器)

时间:2011-02-06 20:58:49

标签: haskell monads monad-transformers haskell-snap-framework

有人可以展示如何在阅读器monad中使用snap monad吗? Monad变形金刚迷惑我。 (或者,我很乐意接受有关monad变换器的教程的建议,以及查看光线并最终了解它们的方法。)

编辑:糟糕;忘了说明我实际上要做的事情,而不是寻求特定事情的帮助。战略,而不是战术。我特别希望在所有处理程序之间共享数据库连接/池,而不必在指定路由时显式传递该数据库连接/池。似乎读者monad将是实现这一目标的方法。

3 个答案:

答案 0 :(得分:5)

Snap具有ApplicationState类型,允许您打包所需的任何应用程序范围的资源(数据库连接,模板引擎等)。

它位于生成的文件Application.hs中,默认情况下将HeistState和TimerState包含在ApplicationState中。您可以将数据库连接放在那里,它可以在Snap应用程序的任何位置使用。

答案 1 :(得分:4)

如果您不害怕使用特定于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)

您现在可以使用asklocal来访问阅读器数据。要在Snap monad中执行操作,您需要将其“提升”到新的monad中。

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

但您可能更喜欢较短的名字。所以,也许只是snap

答案 2 :(得分:0)

假设snap monad来自http://hackage.haskell.org/packages/archive/snap-core/0.4.0/doc/html/Snap-Types.html ... Snap是monad(不是monad变换器),所以你不能在任意monad中运行它。您可以使用ReaderT转换器在Snap中嵌入Reader功能,如果这是您想要的。

runSnap的类型是

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

告诉我们它以Iteratee ByteString IO monad运行。 Reader monad不允许您对输入流执行IO或迭代,因此您无法在Reader monad中运行Snap计算。

如果你解释你想要完成什么,有人可能会建议一种方法来实现它。