问题标签 [state-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 投票
0 回答
1018 浏览

design-patterns - 状态单子和策略模式

我正在重新设计一个库,我对当前的设计模式不满意。这个问题涉及将策略模式State monad结合使用

我有一个Filter. 在其基本实现中,它所做的只是获取一些类型的数据馈送'd并更新自身,生成自身的新更新副本。

然后我有一个ISignalGenerator,它需要一个过滤器、环境数据并对其进行处理以生成一个Signal类型'S

SignalGenerator一个策略模式对象。在SignalGenerator的实现中,库用户挂载将使用和组合以生成Signal.

我可以将我的代码包装在一个状态 monad中。与一些环境变量(数据馈送)一起,状态单子将携带“过滤器”作为状态。SignalGenerator然后将通过 state monad(类型的数据馈送'dFilter) 获取状态更新

我的设计问题是我想将SignalGenerator类型与工作流的开发分离,即我想避免将 state monad 嵌套在SignalGenerator. 是否有功能设计模式来实现这一目标?

编辑

根据 Tomas 的评论,我制作了一个玩具模型。选择策略类是基于将许多函数包装在一起的需要。

我想知道是否会有一种模式解决方案,Strategy该类可以使用已安装的功能,而无需将状态单子嵌套在其腹部。换句话说,有没有办法推迟 的定义let state = StateMonadBuilder<int> (),而不会陷入类型推断头痛?

我对函数式编程和 F# 比较陌生。请让我知道我的问题是否有意义!谢谢。

0 投票
1 回答
182 浏览

monads - 使用理由>>

在 Real World Haskell章节中,他们给出了这样的理由(>>)

当我们想按特定顺序执行操作时,我们会使用此功能,但不关心一个操作的结果是什么。

然后他们举了一个很好的例子来证明它:

在本章的后面,他们使用相同的概念在 State monad 中生成随机值:

put gen' >>但是为什么在这种情况下他们最终会忽略它的输出值时使用该语句。为什么上面的函数不能是这样的:

只是为了完成这个问题,我为上述上下文添加了相关的类型定义和函数:

0 投票
1 回答
162 浏览

f# - 递归更新状态单子

这个问题与这个问题有关

我有一个状态单子。对象提供了OOD 策略模式update中的功能。

  • 拥有一个对象的选择是,在实际的生产代码中,该类提供一组操作,所有操作都通过 monad 共享状态。继承帮助我扩展了基本功能并进一步定制了提供操作的类。
  • 在类中使用 monad 而不是可变属性的选择是,通过正确使用泛型,monad 正在帮助我抽象化并更加灵活地处理必须在计算中作为“状态”携带的变量/信息。

我有一个简单的玩具示例:

我的目标是应用初始条件、获取数据并递归地启动(在一个循环或for一个while循环甚至一些函数操作中)由strategy. 与 monad 一起工作,我不知道该怎么做。

谢谢你。

计算表达式

受@kvb 答案的启发,我for在计算表达式中添加了一个方法。

我进行了一些测试,我的印象是这个有效。谢谢。

0 投票
2 回答
834 浏览

oop - Haskell - 状态单子是命令式思维的标志吗?

我正在写一个简单的游戏——俄罗斯方块。这是我有生以来第一次使用函数式编程来实现这个目标,我选择了 Haskell 作为一门语言。然而,我被 OOP 和命令式思维所污染,并且害怕无意识地将这种思维方式应用到我的 Haskell 程序中。

在我的游戏中,我需要了解经过时间(计时器)和按下/按下键(键盘)的信息。翻译成 Haskell 的 SDL 课程中使用的方法如下所示:

主文件

定时器.hs

然后像这样使用:modifyFPSM $ liftIO . start. 这使得 Timer 有点纯粹(它不是明确的 monad,它的函数返回 IO 只是因为它需要测量时间)。但是,这会在 Timer 模块之外的代码中添加 getter 和 setter。

我在 Keyboard.hs 中使用的方法是:

这使得模块自包含,但我担心这是我在 Haskell 中从 OOP 表达对象的方式并破坏了 FP 的全部意义。所以我的问题是:

这样做的正确方法是什么?或者还有什么其他可能性来处理这种情况?如果您发现任何其他缺陷(无论是设计还是风格问题),请随时指出。

0 投票
4 回答
223 浏览

design-patterns - 如何参数化我的 Haskell 函数?

我希望我的术语在这里是正确的——如果不是,请随时编辑任何内容。

我在写一篇关于组合博弈论的论文时使用 Haskell 作为辅助语言 - 即,我的所有函数都只是处理数字并帮助我为我正在研究的游戏找到解决方案。

我为一个具体的、完整的“棋盘大小”(想想棋盘、5x5 等)编写了所有函数。我想扩展到任何大小的学习板,所以通过包含一个整数参数来修改所有相关函数。例如

然而,这已经开始变得混乱。通常我认为与大小无关的函数在访问需要大小的函数时必须提供大小。

这很快就会导致这样的行:

(请注意,函数的内容实际上并不重要,我只是想展示它变得多么失控。)

我对使用 Haskell 以及一般的函数式编程非常有信心,但我不知道如何才能删除所有这些size引用,而只是依靠其他东西来设置每个需要使用它的函数的大小.

我想我可能正在寻找一个单子,但我不知道。

0 投票
1 回答
556 浏览

f# - State Monad - While 循环

这个问题受到了这个问题的启发。我理解示例(ListBuilder),但我无法while为我的状态单子创建循环。我不清楚的是,随着迭代一个一个地跟随循环bind体。while

谢谢你。

0 投票
0 回答
419 浏览

haskell - 即使 mtl 在 build-depends 中,cabal 构建缺少 Control.Monad.State

我正在尝试构建自己的 cabal 包,其中一个模块使用 Control.Monad.State,但出现以下错误:

我已将 mtl 添加到 build-depends 中但没有成功。我读到其他人在构建分析时遇到问题,而 mtl 不是为此而构建的,但我不应该为分析而构建。我在 ~/.cabal/config 中将库分析和可执行分析都明确设置为 False。

我在 Mac 操作系统上

0 投票
2 回答
487 浏览

arrays - 我应该如何结合 St monad 和 State monad(或等效)?

我正在构建代码以获得理解,实际上是一个纸牌求解器。我有一个简单的蛮力实现,它使用 State monad,实际上只是为了证明我可以使用它(它只记录评估的每个动作的计数)。但是现在我想使用 Unboxed Mutable 数组来记录访问过的电路板,从而在我到达已经通过另一条路径访问过的电路板位置时对路径进行快捷评估。似乎 ST monad 不允许我线程隐式状态,但我必须使用 ST(或 IO)才能访问 Mutable 数组。所以看来我必须结合两个 Monad - State 来线程化状态(实际上将包括一个 Mutable 数组),另一个(ST)来获得 Mutable 数组函数。

  • 这是正确的吗?
  • 如果是这样,是否有比 Data.Array.ST/Control.Monad.ST/Control.Monad.ST 和 mtl 的(规范?)组合更好的选择?
  • 如果我真的走这条路,我堆叠 ST 和 State 的顺序是否重要?
  • 我是否应该考虑基于 ST 或 State 中的一个或两个来滚动我自己的单个 Monad 以避免使用 monad 转换器?
0 投票
4 回答
130 浏览

haskell - 我是否遗漏了关于 State Monad 的一些基本内容?为什么要分开保存状态和输入?

为什么我们的函数需要接受状态和输入,而不仅仅是包含输入的状态(或包含状态的输入?)。

我假设您可能希望应用具有相同状态的不同输入,因此您希望将它们分开保存,但这是唯一的原因吗?

觉得我错过了一些基本的东西,但我无法掌握它。

0 投票
1 回答
195 浏览

haskell - 如何在Haskell中无限期地在同一个State monad中线程化一个状态?

从 Haskell 开始,一直停留在 State Monad ......

所以我试图掌握 Haskell 中的 State Monad,为了理解它,我正在编写一个代码来生成 PRBS 序列。对于感兴趣的人,它在论文 'Pseudo Random Sequences and Arrays' 中进行了描述,可以通过 doi:10.1109/PROC.1976.10411 获得其免费副本。

基本计算非常简单。你有一个移位寄存器和一个生成多项式。生成多项式告诉您取移位寄存器的哪些位并求和(模 2)以获得移位寄存器的 MSB。在下一次迭代中,您将计算出的 MSB 并在执行右移操作后将其粘贴到移位寄存器的 MSB 上。

在没有 monad 的情况下执行此操作的代码非常简单:

输出如下:

这就是我想要的。

当然,既然移位寄存器可以被认为是我们修改的状态,我们可以为此目的使用状态单子。也许学习状态单子太简单了,我似乎只是认为这可能是一个可以使用状态单子实现的完美示例。所以这就是我所做的:

这只是添加到前面的代码段,以及import Control.Monad.State程序的第一个类似部分。当我将其导入 GHCI 并检查状态计算时,我可以获得如下所示的单个值:

因此,状态正在正确更新并且返回的值也是正确的。现在我想创建一个类似于word之前实现中的函数的函数,它将在s次上应用>>运算符,以便我们可以创建数组。我完全不知道如何去做这件事。请注意,我不想放入一组函数,例如:bitMnword p s

我想要一个我将传递给它的函数,它将n连续多次进行bitM评估n,在连续计算中自动在内部传递状态,收集结果值,并创建一个数组作为结果。我该怎么做呢?我不知道该怎么做。任何帮助将不胜感激!