问题标签 [st-monad]

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 回答
1452 浏览

haskell - Haskell——双重人格IO / ST monad?

我有一些代码目前使用 ST monad 进行评估。我不喜欢将 IO 放在任何地方,因为该runST方法会产生纯结果,并表明这样的结果可以安全调用(相对于unsafePerformIO)。但是,由于我的一些代码变得更长,我确实想将调试打印语句放入其中。

是否有任何类提供双重人格 monad [或 typeclass 机器],可以是 ST 或 IO(取决于其类型或“isDebug”标志)?我记得 SPJ 在他的“Fun with Type Functions”论文中引入了一个“Mutation”类,它使用关联类型将 IO 与 IORef 和 ST 与 STRef 相关联。这样的东西在某处作为一个包存在吗?

编辑/解决方案

非常感谢 [第 n 次],CA McCann!pdebug使用该解决方案,我能够为支持函数的 monad 引入一个附加类。monad将ST忽略这些调用,而IO将运行putStrLn.

这在 ghci 中有一个非常幸运的结果。由于默认情况下它期望表达式是 IO 类型,运行类似“test 3”的东西会导致 IO monad 被运行,所以你可以很容易地调试它,然后当你真正想要运行时用类似“testR”的东西调用它它。

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 回答
213 浏览

arrays - 从 STArray 中提取元素(类似于解压缩)

我在 Haskell 中为编程竞赛实施基于粒子的流体模拟时遇到了一个小问题。我目前有一组粒子,它们在每个模拟步骤中都会被修改。每个粒子都是 2 个向量的元组:位置和速度(我自己的 Vec3D 模块)。在某些时候,我需要从我试图这样做的粒子(有点像解压缩列表)中提取位置:

whereps'doubleDensityRelaxationare 类型

所以xs应该是 type xs :: Array Int Vec3D。但是,我得到

来自我不太了解的编译器,因为它readArray不应该返回整个数组;只有一个(Vec3D, Vec3D)元素。

作为修复,我可以直接 doubleDensityRelaxation拍摄吗?ST s (STArray s Int Vec3D)

如果我改变这样的类型并删除let xs = runSTArray $ do我得到的部分

但是如果我将它(ST s xs')作为输入而不是仅仅xs'抱怨数据构造函数ST不在范围内。我的进口目前是

功能齐全:

0 投票
1 回答
957 浏览

haskell - 这种类型的签名发生了什么?(Haskell 中的 Vector.Mutable 修饰符)

Haskell 中的可变向量具有三个元素级别的修改器:

现在我可以很好地使用这些——

但是这里发生了什么?什么是PrimMonad? 并且是PrimState构造函数?

我知道这里有一些绑定,在一个PrimMonad类单子上。thaw返回m (MVector (PrimState m) a)ma在哪里PrimMonad...但是 monad 包含自己?为什么m在另一个上下文中m

我看到一切基本上都绑定在 this PrimStateor上PrimMonad,但我不明白这与可变/可存储向量有什么关系。那些允许它们存储状态的类型类有什么特别之处吗?

感谢您的时间!

0 投票
1 回答
359 浏览

arrays - 使用并返回多个 STUArray

我一直在研究如何在 ST 计算中创建和使用多个 STUArray。具体场景如下:

  1. 创建多个数组但只返回其中一个
  2. 创建多个数组但不返回任何一个
  3. 创建多个数组并返回多个数组

我有(1)和(2)的答案,但没有(3)。

首先是一些导入,以便我们知道所有内容的来源:

对于 (1),一个技巧是定义一个新的数据类型和构造函数:

以下是仅返回其中一个数组的方法:

对于 (2),您可以将 an 添加STRef到数据结构中,使用 a 结束计算并使用readSTRef运行它runST

对案例 (1) 和 (2) 的这种方法有何评论?那么情况(3)呢?

0 投票
1 回答
1402 浏览

haskell - 如何将可变向量放入状态单子

我在 haskell 中编写了一个小程序,使用带有 Vector 的 State Monad 来计算 Tree 中所有 Int 值的出现次数:

但是不可变向量的“更新”是以 O(n) 复杂度完成的。我正在寻找 O(1) 中的更新和 O(1) 中的访问。据我了解,可变向量做我想做的事。要使用它们,我需要使用 ST 或 IO。因为我想做一些单元测试,所以我更喜欢 ST monad,但我不想在函数调用中传递那个向量。我需要继续使用 Monad Transformers,因为我将添加像 ErrorT 和 WriterT 这样的转换器。

问题:如何使用 Monad Transformers 将可变向量放入 State Monad?

我想出了以下无法编译的代码:

编译错误是:

注意:我知道不检查边界。

0 投票
1 回答
125 浏览

haskell - 使用 Monad/ST 在可变图中传递非并发消息

我正在尝试为以下情况制定数据结构。

图结构

我计划制作一个带有未加权有向边的节点图:Graph = [Node]

每个节点有:

  1. 一些待定内部(持久)状态
  2. 传入消息队列
  3. 它可以发送的一种消息,由接受当前节点状态的函数确定(有失败的可能性)
  4. 边列表

Node { nodeState :: NodeState, inbox :: Queue NodeMessage, nodeMessage :: (NodeState -> Maybe NodeMessage), connections::[NodeEdge] }

每条边都是一个中间步骤,用于捕获目标节点的未决消息

NodeEdge { pendingMessage:: Maybe NodeMessage, targetNode :: Node }

消息传递

消息传递是分阶段进行的,并且是不同步的(尽管队列可以并行处理以减少计算时间)。

  • 第 1 阶段:检查每个节点的收件箱,处理任何消息并更新NodeState相关信息。
  • 第 2 阶段:让每个节点运行nodeMessage,如果这导致Just NodeMessage,将 NodeMessage 发送到每个连接([NodeEdge]
  • 阶段 3:检查每个节点边缘,如果有消息,则将其添加到目标节点的消息队列中。

莫纳特/ST

我最初的计划是为每个节点分配一个 ID(可能是一个简单的 Int)并将每个节点存储在 Map Int 节点中。我之前没有尝试过 ST Monad,但我想我可以使用类似ST s (M.Map Int Node). 对于任何给定阶段,每个节点的消息发送活动都可以在 O(k log N) 中处理。

另一方面,如果节点/边能够更新其边/节点的可变状态,那么任何单个队列都可以在 O(k) 中处理。

虽然 ST/Map 方法看起来相当直观,但让整个图可变却超出了我的范围。

有什么建议/提示/推荐阅读吗?

0 投票
1 回答
249 浏览

haskell - 使用 ST Monad 混合 IO -“类型变量 `s2' 将超出其范围”

我决定简化我的代码,看看是什么条件产生了错误。我从一个简单的嵌套“s”开始,ST s (STArray s x y)类似于这样:

为了测试状态代码,我运行以下转换:

我想在保持状态的同时从状态中提取一个值,所以下一步是提取 Bool 值:

为了提取该 Bool 我必须使用runST. 我的理解是,这将创建一个额外的状态,我通过forall s.在返回类型中提供 a 来指定它:

上面的示例确实在没有 final 的情况下编译,forall但是在我尝试调试的情况下这是不可能的。无论如何,在这种情况下,它可以编译任何一种方式。

我可以使用上面的代码将状态的多种用途链接在一起:

现在我尝试将 IO 加入其中,因此我使用了应用程序 fmap <$>。这不编译:(注意,如果我使用fmapor>>= return而不是同样的问题<$>

出现以下错误:

我从这个关于 ST 函数组合的 SO 问题中知道,并非所有可能的 ST 用途都由编译器考虑。为了测试这个假设,我修改了上面的函数以不使用 IO 并简单地将返回值传递给 lambda:

可以预见的是,这也不会与相同的错误消息一起编译。

这提出了一个挑战。我有合理数量的 IO 需要与一组深度嵌套的 ST 操作进行交互。它对于单次迭代非常有效,但是我无法进一步使用返回值。

0 投票
1 回答
172 浏览

arrays - 如何通过 1)使用数组,2)避免列表连接(惰性列表?)来改进此算法?

我试图了解 STArray 的工作原理,但我做不到。(Doc很差,或者至少是我找到的那个)。

无论如何,我有下一个算法,但它使用了很多!!,这很慢。如何将其转换为使用 STArray monad?

编辑

哎呀,!!不是问题;在算法的下一个版本(如下)中,我删除了 !! 的使用;另外,我将 1 固定为素数,正如@pedrorodrigues 所指出的那样

现在这个问题实际上是关于 2 个问题:

1.- 如何将此算法转换为使用数组而不是列表?(是为了学习如何在 Haskell 中处理状态和数组)有人已经在评论中回答了,但指向一个不太好的解释示例。

2.- 每次找到新素数时如何消除列表的串联?

真 -> primesAcum++[当前]

0 投票
3 回答
382 浏览

scalaz - 如何在没有副作用的情况下在 Scala 中实现 Fisher-Yates shuffle?

STArray我想通过使用局部突变效果和功能随机数生成器来实现没有副作用的 Fisher-Yates 算法(就地数组洗牌)

产生算法所需的随机整数。

我有一种方法def intInRange(max: Int): RNG[Int]可以用来Int在 [0,max) 中产生随机数。

来自维基百科

我想我需要以某种方式堆叠StateST但这让我感到困惑。我需要一个[S]StateT[ST[S,?],Seed,A]吗?我是否也必须重写RNG才能使用StateT

(编辑)我不想参与IO,也不想替代VectorSTArray因为洗牌不会就地执行。

我知道这里有一个 Haskell 实现但我目前无法理解并将其移植到 Scalaz。但也许你可以?:)

提前致谢。