问题标签 [monad-transformers]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
562 浏览

haskell - 将单子组合抽象为变压器

对不起,如果这个问题看起来有点微不足道......它不适合我。我很高兴地编写了以下单子:

这是一个行为良好的单子。ReaderT 是一个 monad 转换器,State 是 State monad,AlgRO 和 AlgState 是在 i 中参数化的数据类型,分别用于可变和只读状态。现在,如果我想用 newtype 制作一个整洁的 monad 转换器,如下所示:

我应该如何进行?我什至无法将(Monad 类型类的)绑定方法放在一起,更不用说(MonadTrans 的)“提升”了......我想自动推导可能会有所帮助,但我想了解它在这种情况下是如何工作的。

提前致谢。

0 投票
2 回答
820 浏览

haskell - 有没有更好的方法在 Haskell 中实现多通道 Writer monad?

问题:

我需要在同一个 Haskell monad 转换器堆栈中编写不同类型的 writer monad。除了tell用于编写调试消息之外,我还想用它来编写一些其他数据类型,例如要在其他上下文中传输的数据包。

我已经检查了 Hackage 的通道化作家单子。我希望找到的是一个支持多种数据类型的类似 writer 的 monad,每种数据类型在runWriter结果中代表一个不同的“逻辑”通道。我的搜索没有发现任何东西。

解决方案尝试1:

我解决问题的第一种方法是WriterT沿着这些线堆叠两次:

MStack但是,我在声明为MonadWriter [Packet]and的实例时遇到了问题MonadWriter [String]

来自 ghci 的后续投诉:

我理解为什么这种方法无效,如此处所示,但我无法找到解决基本问题的方法,所以我完全放弃了它。

解决方案尝试 2:

由于看起来堆栈中只能有一个WriterT,因此我使用了一个包装器类型,Packet并将String事实隐藏在实用程序函数(runMStack、、tellPackettellDebug下面)中。这是有效的完整解决方案:

耶,编译和工作!

解决方案非尝试 3:

我还想到,这可能是我自己动手的时候,还包括错误、读取器和状态单子功能,这些功能需要存在于我的实际应用程序的转换器堆栈类型中。我没有尝试这个。

问题:

虽然解决方案 2 有效,但有没有更好的方法?

此外,可以将具有可变数量通道的通道化 writer monad 通常实现为包吗?看起来这将是一件有用的事情,我想知道为什么它还不存在。

0 投票
2 回答
198 浏览

haskell - 需要 MonadPlus (ST a) 实例

我正在阅读Haskell 中的 Typed Logical Variables论文,但我无法理解最终实现的细节。特别是第 4 节中介绍的回溯状态转换器。出于某种我不知道的原因,GHC 认为我需要在函数中的MonadPlus实例,如下所示:(ST a)unify

我不确定问题是什么,以及如何解决它。到目前为止,我的印象是我理解了前面的讨论和代码,但显然我错了。如果有人能指出出了什么问题——我是否需要一个MonadPlus (ST a)实例?- 这将非常有帮助。

[编辑:澄清]我应该指出,作者似乎声称mzero或 的某些变体mzero是适当的功能。我只是不知道合适的功能是什么。我想知道是我应该创建一个MonadPlus (ST a)实例还是我没有使用正确的功能,并且误读了一些东西。

0 投票
1 回答
1378 浏览

scala - scalaz List[StateT].sequence - 找不到参数 n 的隐式值:scalaz.Applicative

我试图根据对我的Scalaz 状态单子示例答案的评论来弄清楚如何使用StateT组合两个状态转换器。State

看来我已经很接近了,但是在尝试申请时遇到了问题sequence

所以我得到了一个StateT[StateMap, Random, Int]我可以用初始随机和空地图状态展开的:

现在我想生成一个列表StateT并使用sequence,以便我可以调用list.sequence ! new Random(1L) apply Map[Int,Int](). 但是当我尝试这个时,我得到:

任何的想法?我可以在最后一段时间使用一些帮助 - 假设它是可能的。

0 投票
2 回答
869 浏览

haskell - 如何在 Happstack 中创建数据库单子堆栈?

我想创建一个可以大量访问数据库的 Happstack 应用程序。我认为底部带有 IO 的 Monad 堆栈和顶部的类似数据库写入的 monad(中间带有日志写入器)将有助于在每次访问中具有清晰的功能,例如:

和:

但是我对 Monad 和 Monad Transformers 知之甚少(我将这个问题视为学习它的练习),并且我不知道如何开始创建 Database Monad,如何将 IO 从 happstack 提升到 Database Stack, ...ETC。

0 投票
1 回答
573 浏览

scala - 用于理解的 Monad 转换器

考虑:

现在我会写一个类似的方法:

但当然这不会编译,因为推断的类型是 Option[Option[Long]]。

在 scala 语法和标准库方面有没有办法获得 Option[Long]?我知道我可以进行模式匹配,但是刚刚出现了是否可以使用 for 理解来完成的问题。


感谢 Tenshi 的回答,这可以完成工作,但是我刚刚遇到了另一个问题示例:

我可以a在 for as 中添加:a <- Some(A(c))但是隐含的呢?这是否意味着我的代码中的设计更改?

0 投票
2 回答
1698 浏览

parsing - 底层 Parsec Monad

我使用的许多 Parsec 组合器属于以下类型:

CharParser这里定义为:

CharParser因此是一个涉及 的类型同义词GenParser,它本身在这里定义为:

GenParser然后是另一个类型的同义词,使用 分配,这里Parsec定义为:

Parsec的部分应用也是如此,它本身在此处以类型ParsecT列出:

连同的话:

“ParsecT suma 是一个具有流类型 s、用户状态类型 u、底层 monad m 和返回类型 a 的解析器。”

什么是底层的单子?特别是,当我使用CharParser解析器时它是什么?我看不到它在堆栈中的插入位置。在 Haskell 的 Monadic Parsing 中使用 list monad从一个模棱两可的解析器返回多个成功的解析是否有关系?

0 投票
2 回答
578 浏览

performance - 来自 monad 变压器基准测试的奇怪结果。一个错误?

我做了一些 Criterion 基准测试来估计通过在 monad 堆栈上运行我的代码会损失多少性能。结果相当奇怪,我可能在我的基准测试中偶然发现了一些懒惰的陷阱。

基准测试告诉我,运行WriterT String IO比普通运行慢 20 倍(!)IO,即使不使用tell. 奇怪的是,如果我堆叠WriterT起来ReaderTContT它只会慢 5 倍。这可能是我的基准测试中的一个错误。我在这里做错了什么?

基准

结果

0 投票
1 回答
529 浏览

haskell - Haskell ReaderT Env IO 样板

我有以下我经常做的样板,并且想消除。它看起来像这样:

我想把它减少到这样的事情:

不幸的是,我还没有完全把注意力集中在 monad 转换器上。是什么类型的find?是(Config -> IO Result) -> Result吗?我该怎么写?

非常感谢任何帮助我 grok monad 转换器的提示/解释。

谢谢!

0 投票
3 回答
409 浏览

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

动机。我正在尝试创建一个 monad 转换器,其特殊指令f <||> g表示“重复整个块,其中包含f <||> g一次f,下一次使用g”。这旨在用于 DSL 转换,尽管您可以想象其他应用程序。

示例用法computationmonad 表达了不同的可能选择(在这种情况下,是要打印的东西)。该printme函数说明如何处理每个不同的结果。在这种情况下,我们在运行之前打印“开始计算”,之后打印“---”。

输出如下,

问题。有没有一种干净的方法可以使用某种延续传递风格的单子变压器来实现上述行为?我查看了 Oleg 等人的“Backtracking, Interleaving, and Terminating Monad Transformers”论文,但似乎无法完全掌握它们的实现(一旦他们msplit使用延续实现)。

当前实施。我当前的实现是传入要做出的分支决策列表。monad 将返回它实际选择的分支列表,然后下次我们将切换最后一个可能的分支。代码如下(应该在7.0.3运行),