haskell - 具有多个相同变压器的 monad 堆栈

标签 haskell monads monad-transformers

我正在尝试编写自己的 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 都有唯一的阅读类型。是否有针对同一堆栈上的多个变压器的标准解决方法?我应该尽量避免这种情况吗?

最佳答案

使用变压器和电梯进入你的内心单子(monad):

import Control.Monad.Trans.Reader
import Control.Monad.Trans.Class (lift)

type MyMonad a = ReaderT Bool (Reader Char) a

askBool :: MyMonad Bool
askBool = ask
askChar :: MyMonad Char
askChar = lift ask

您提供的代码没有(直接)使用任何单子(monad)转换器。它使用了 reader monad(恰好是一个应用于 identity monad 的转换器)和 MonadReader类型类。正如您所注意到的, MonadReader 隐含的类型函数不能为同一输入(monad m)产生两个不同的输出(环境类型)。

关于haskell - 具有多个相同变压器的 monad 堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54153080/

相关文章:

haskell - Haskell 是 self 定义的吗?

scala Iterable#map 与 Iterable#flatMap

scala - Stackless Scala 和 Free Monads,完整示例

haskell - 处理置换的单子(monad)变压器堆栈

haskell - 我无法理解维基百科对 "applicative functor"的定义

haskell - 当类型类只有一个时,具有 2 个参数的类型的类型类实例

haskell - 在 Haskell 中使用表情符号

haskell - Haskell 的 "do"问题

haskell - 我怎样才能继续实现这个monad转换器?

haskell - 整理 Monads - 将 monad 转换器的应用程序转变为新型 monad