假设我们想在 ReaderT [(a,b)] monad 上使用 Maybe,然后我们想在列表中进行查找。

现在,一种简单但不太常见的方法是:

第一种可能性

find a = ReaderT (lookup a)

然而,这似乎确实断言了关于 ReaderT 转换器如何工作的一些重要事情。查看 Control.Monad.Reader 的源代码,很明显这工作得很好。但我还没有阅读任何支持这一点的文档。但是我们也可以这样写 find :

第二种可能性
find a = do  y <- ask
             lift (lookup a y)

类似的想法适用于包装 MaybeTStateTStateReader 。通常我会像第一个例子那样写一些东西,但大多数时候如何像第二个例子一样编写它真的很明显,你甚至可能会说它更具可读性。所以我的问题是:像第一个例子这样的代码应该被认为是坏的吗?

最佳答案

当前版本的 mtl 库(基于 转换器 库)在使用简单的 reader :: (r -> a) -> Reader r a monad 时正是出于此目的导出函数 Reader。所以我们看到库的设计确实考虑到了这种用法。由于没有为 ReaderT 提供这样的函数,我们可以有信心地说,官方支持的使用 ReaderT 做到这一点的方法是直接使用构造函数。

如果您说应该将类似的 readerT :: Monad m => (r -> a) -> ReaderT r m a 添加到库中,我会同意您的看法。这对一致性和允许在不破坏任何人的代码的情况下有一天改变内部表示的可能性都有好处。

但就目前而言,您的“第一种可能性”是要走的路。

关于haskell - 是否/应该将函数包装到 monad 转换器中被认为是不好的做法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4317101/

10-12 20:20