【发布时间】:2019-01-11 19:42:35
【问题描述】:
我试图编写自己的 monad 转换器,在堆栈中拥有多个具有不同类型的相同 monad 转换器是有意义的。这个问题可以用 reader monad 来说明。
reader monad 被提供为一种保存给定类型的只读上下文的方式
ex1 :: Reader Bool Bool
ex1 = ask
或
ex2 :: Reader Char Bool
ex2 = pure True
monad 转换器允许对下划线 monad 进行较少限制的假设
ex3 :: (MonadReader Bool m) => m Bool
ex3 = ask
但是,如果我想拥有多个只读环境怎么办?我可以写一个类似的函数
ex4 :: (MonadReader Bool m, MonadReader Char m) => m Bool
ex4 = ask
但是,据我所知,没有办法运行 ex4,因为
class Monad m => MonadReader r m | m -> r
表示每个 MonadReader 都有唯一的阅读类型。是否有针对同一堆栈上的多个变压器的标准解决方法?我应该尽量避免这种情况吗?
【问题讨论】:
-
lift ask不工作吗? -
@arrowd 类型签名本身就是非法的。 MonadReader 类型类有一个函数依赖,它表示 monad
m必须唯一地确定正在读取的类型。如果您使用显式的 monad 转换器堆栈而不是类型类,它确实有效 -
请记住
MonadReader不是变压器。如果您使用变压器,例如transformers包,并且避免考虑mtl提供的条款,那么您会做得很好。
标签: haskell monads monad-transformers