【问题标题】:Learning Happstack and Monad Transformers学习 Happstack 和 Monad 变形金刚
【发布时间】:2013-07-02 08:54:41
【问题描述】:

所以我有一个项目,我认为学习起来很简单,但又足够复杂,很有趣,我想使用 Happstack 库来编写。在最基本的层面上,这个项目只是一个花哨的文件服务器,带有一些特定于域的 REST 方法(或者其他什么,我真的不在乎它是否真的是 RESTful)来搜索和获取所述文件和元数据。由于我现在也在尝试真正学习 monad 转换器,因此我认为这将是一个完美的学习项目。但是,我在启动它时遇到了一些困难,尤其是在如何构建我的变压器堆栈方面。

现在,我只担心几件事:配置、错误报告、状态和日志记录,所以我开始了

newtype MyApp a = MyApp {
    runMyApp :: ReaderT Config (ErrorT String (StateT AppState IO)) a
} deriving (...)

由于我总是在 IO 中,我可以很容易地使用 hslogger 来处理我的日志记录。但我也知道我需要使用ServerPartT 来与 Happstack 交互,因此

runMyApp :: ReaderT Config (ErrorT String (StateT AppState (ServerPartT IO))) a

我可以让它运行,查看请求等,但我遇到的问题是这需要为它实现FilterMonad,以便使用dirpath 和@987654329 等方法@,但我不知道如何为这种类型实现它。我只需要它将过滤器传递给底层的 monad。有人可以给我一些关于如何实现这个明显至关重要的类型类的指示吗?或者,如果我只是在做一些非常错误的事情,请引导我朝着正确的方向前进。我只关注 Happstack 几天,变形金刚对我来说还是很陌生。我认为我对它们的了解足以使它们变得危险,但是我对它们的了解还不够,以至于我可以自己实现一个。非常感谢您提供的任何帮助!

FULL CODE

(X-发自/r/haskell

【问题讨论】:

    标签: haskell monad-transformers happstack


    【解决方案1】:

    对你来说最简单的事情就是从你的堆栈中删除 ErrorT。如果您查看here,您会看到 Happstack 为 StateT 和 ReaderT 定义了 FilterMonad 的内置直通实例,但没有为 ErrorT 定义。如果您真的想将 ErrorT 保留在您的堆栈中,那么您需要为它编写一个直通实例。它可能看起来很像 ReaderT 的那个。

    instance (FilterMonad res m) => FilterMonad res (ReaderT r m) where
        setFilter f   = lift $ setFilter f
        composeFilter = lift . composeFilter
        getFilter     = mapReaderT getFilter
    

    我倾向于认为您不应该将 ErrorT 融入您的应用程序 monad,因为您不会总是处理可能失败的计算。如果您确实需要在代码的某个部分中处理故障,您总是可以通过将runErrorT 包裹在该部分周围,然后根据需要使用ErrorTliftreturn 来轻松地投入其中。此外,变压器堆栈中的额外层会在每次绑定时增加性能税。因此,虽然 monad 转换器的可组合性非常好,但当性能是一个重要考虑因素时,您通常希望谨慎使用它们。

    另外,我建议使用 EitherT 而不是 ErrorT。这样您就可以使用奇妙的errors package。它有很多非常常用的便利功能,如hushjust等。

    此外,如果您想查看您正在尝试做的事情的真实示例,请查看 Snap 的Handler monad。您的 MyApp monad 正是 snaplets 旨在解决的问题。 Handler 有一些额外的复杂性,因为它旨在以一种通用的方式解决问题,这样 Snap 用户就不需要自己构建这个通用的转换器堆栈。但是,如果您查看underlying implementation,您会发现它的核心实际上只是将 Reader 和 State monad 浓缩为一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 2020-05-20
      • 2020-11-18
      • 2020-08-29
      • 2015-10-09
      • 1970-01-01
      相关资源
      最近更新 更多