将嵌套类型转换为 monad 转换器堆栈

Converting a nested type into a monad transformer stack

我在 Haskell Programming From First Principles 的 Monad Transformers 章节中的一个练习中遇到了一些问题。具体来说,我们得到一个看起来像 (const (Right (Just 1))) 的结构,并被要求完成以下内容:

import Control.Monad.Trans.Except
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Reader

embedded :: MaybeT (ExceptT String (ReaderT () IO)) Int
embedded = ??? (const (Right (Just 1)))

我假设这意味着我们无法更改嵌套结构,尽管说明仅针对 "make it work."

在断定我被卡住了之前,我已经走了几条路。到目前为止,据我所知,monad 转换器最常由 lifts 和 dos 的组合创建——除了 SO Q&A,Diehl summarizes pretty well here

我也一直在使用 transformers 库中的 map<Monad>T 变体来获得一些有趣/有趣的结果,但我似乎无法找到解决原始问题的方法.任何提示将不胜感激 — 但是,如果您 post 一个解决方案,please use the spoiler markup(尽管我从未见过它用于除 Puzzling 以外的任何地方)。

这个练习真正展示了 monad 转换器有时是如何工作的 "inside out"。首先弄清楚如何包装该表达式,以便获得类型

的内容
ReaderT () IO (Either String (Maybe Int))

然后想办法得到MaybeT。等等

不要忘记您可以使用 ReaderTEitherTMaybeT 数据构造函数!

如果您还没有尝试 GHC 的 打字孔 ,现在正是尝试的好时机。