【问题标题】:Using the reader monad in snap (or, monad transformers in snap)在 snap 中使用 reader monad(或在 snap 中使用 monad 转换器)
【发布时间】:2011-06-22 09:52:30
【问题描述】:

有人可以展示如何在 reader monad 中使用 snap monad 吗?单子变压器让我感到困惑。 (或者,我很乐意接受有关 monad 转换器的教程的建议,以及看到光明并最终了解它们的方法。)

编辑:哎呀;忘记具体说明我实际上要做什么,而不是就特定的事情寻求帮助。战略,而不是战术。我特别想在所有处理程序之间共享一个数据库连接/池,而不必在指定路由时显式传递该数据库连接/池。似乎 reader monad 将是实现这一目标的方法。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 这必须是自我使用的上一个 snap 版本以来的新版本(0.2.x 的东西。不久前,我知道。),但它正是我想要的。谢谢。
    【解决方案2】:

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

    【讨论】:

    • 你甚至不需要newtype,它可能只是一个类型的同义词:type MyMonad = ReaderT ReaderData Snap。然后使用标准的lift :: Snap a -&gt; MyMonad a
    • ReaderData 这里只是我想要的阅读器的类型,我假设?
    • @tehgeekmeister:是的。 @luqui:根据我的经验,不使用新类型通常会导致进一步的问题。
    【解决方案3】:

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

    runSnap的类型是

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

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

    如果您解释了您想要完成的任务,有人可能会建议一种实现它的方法。

    【讨论】:

    • 更新以反映我真正追求的东西,对此感到抱歉。
    猜你喜欢
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2021-03-04
    相关资源
    最近更新 更多