问题标签 [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 投票
8 回答
14212 浏览

haskell - 使用 Haskell state monad 有代码味道吗?

上帝我讨厌“代码气味”这个词,但我想不出更准确的说法。

我在业余时间为Whitespace设计高级语言和编译器,以了解编译器构造、语言设计和函数式编程(编译器是用 Haskell 编写的)。

在编译器的代码生成阶段,我必须在遍历语法树时维护“状态”数据。例如,在编译流控制语句时,我需要为要跳转到的标签生成唯一名称(从传入、更新和返回的计数器生成的标签,并且不得再次使用计数器的旧值)。另一个例子是当我在语法树中遇到内联字符串文字时,需要将它们永久转换为堆变量(在 Whitespace 中,字符串最好存储在堆中)。我目前正在将整个代码生成模块包装在 state monad 中来处理这个问题。

有人告诉我,编写编译器是一个非常适合函数式范例的问题,但我发现我设计它的方式与我在 C 中设计它的方式非常相似(你真的可以用任何语言编写 C - 甚至带有状态单子的 Haskell)。

我想学习如何在 Haskell 中思考(而不是在函数范式中)——而不是在带有 Haskell 语法的 C 中。我真的应该尝试消除/最小化 state monad 的使用,还是它是一种合法的功能性“设计模式”?

0 投票
3 回答
1107 浏览

haskell - 在 Haskell 中,'get' 实际上是如何 /get/ 初始状态的?

我有一个功能:

我几乎可以理解整个函数中发生的事情,并且我开始掌握 monads 的窍门。我不明白的是,当我运行这个时:

'test' 中的 'get' 函数以某种方式获取初始状态“testtest”。有人可以分解并向我解释吗?

我很感激任何回应!

0 投票
3 回答
976 浏览

haskell - 如何在 Haskell 中以隐藏的方式初始化状态(就像 PRNG 一样)?

我浏览了一些关于 State monad 的教程,我想我明白了。

例如,在这个不错的教程中:

好的,所以我可以使用 getRandom:

但是我每次调用它时仍然需要将种子传递给 PRNG。我知道 Haskell 实现中可用的 PRNG 不需要:

所以我可能误解了 State monad,因为我在大多数教程中看到的似乎不是“持久”状态,而只是一种方便的线程状态方式。

那么......我怎样才能拥有自动初始化的状态(可能来自使用时间和其他不可预测数据的某些函数),就像 Random 模块一样?

非常感谢!

0 投票
3 回答
1298 浏览

haskell - 使用 State monad 还是递归传递 state 更好?

我只是在学习 Haskell,并试图找出实现视线算法的最惯用的方法。

我找到的演示代码使用了 state monad,但对我来说(我只是一个初学者)递归地传递 state 似乎更简单。我在这里想念什么?是否存在性能问题?

在以下位置查找代码:http ://www.finalcog.com/bresenham-algorithm-idiomatic-haskell

谢谢,

克里斯。

0 投票
3 回答
2698 浏览

haskell - 状态单子,随机数序列和单子代码

我试图掌握状态单子,为此我想编写一个单子代码,该代码将使用线性同余生成器生成一系列随机数(可能不好,但我的目的只是学习状态单子,而不是建立一个好的RNG库)。

生成器就是这样(为简单起见,我想生成一个Bools 序列):

不要担心数字,这只是种子的更新规则(根据数字食谱)应该生成Ints 的伪随机序列。现在,如果我想按顺序生成随机数,我会这样做:

好的,所以我可以通过使用 State Monad 来避免这个样板:

最后:

好的,这很好用,并Bool为每个给定的种子给我一个 n 伪随机的列表。但...

我可以阅读我所做的(主要基于这个例子:http ://www.haskell.org/pipermail/beginners/2008-September/000275.html )并复制它来做其他事情。但我认为我无法理解 do-notation 和 monadic 函数(如 replicateM)背后真正发生的事情。

任何人都可以帮助我解决一些疑问吗?

1 - 我试图对 nextVal 函数脱糖以了解它的作用,但我做不到。我猜它会提取当前状态,更新它,然后将状态传递给下一个计算,但这只是基于阅读这个 do-sugar 就好像它是英语一样。

我如何真正将这个函数脱糖到原来的 >>= 并逐步返回函数?

2 - 我无法掌握putandget函数的确切作用。我可以猜到他们“打包”和“解包”状态。但糖背后的机制对我来说仍然难以捉摸。

好吧,非常欢迎有关此代码的任何其他一般性评论。我有时会迷恋 Haskell,因为我可以创建一个可以工作的代码并按照我的预期去做,但我不能像我习惯于使用命令式程序那样“遵循评估”。

0 投票
2 回答
3306 浏览

haskell - Haskell Monad Transformer 堆栈和类型签名

我正在尝试创建一堆 monad 转换器,但无法为我的函数获取正确的类型签名。(我对 Haskell 还是很陌生)

该堆栈结合了多个 StateT 转换器,因为我需要跟踪多个状态(其中两个可以被元组化,但我会在一秒钟内完成)和一个用于日志记录的 WriterT。

这是我到目前为止所拥有的:

我想popLine弄乱[Line]状态和xLineNum影响Int状态的功能。evalr是将传递给 的计算runPass1

每当我加载代码时,我都会遇到以下错误:

没有一个签名似乎是正确的,但 popLine 是第一个函数,所以它是唯一一个立即导致错误的函数。

我尝试在类型签名中添加它所建议的内容(例如:popLine :: (MonadState [Line] m) => ...但随后出现如下错误:

每当我尝试做一些不是类型变量的事情时,我似乎总是会收到这条消息。它似乎喜欢(MonadState s m)在其他东西上 ok 和 error,但是当我用 a[a]而不是sit 尝试它时,错误类似于上面。(最初 [Line] 和 Int 在一个状态下进行元组处理,但我收到了这个错误,所以我想我会尝试将它们置于不同的状态)。

GHC 6.10.4,库本图

那么,谁能告诉我发生了什么并给出解释/向我展示正确的类型签名,或者有没有人知道关于这些东西的一个很好的参考(到目前为止唯一有帮助的是“Monad Transformers Step by Step” ,但只使用一个辅助状态函数和一个StateT)?

提前谢谢了。

编辑
这是包含 JFT 和 Edward 建议的编译代码:

我结合incLineNumpopLine进入nextLine我仍然需要让 Writer monad 部分工作,但我想我知道从这里去哪里。多谢你们。

0 投票
2 回答
160 浏览

haskell - StateT 和 WX gui 共存

通常的 wxHaskell 程序看起来像

gui 必须有类型IO a,run 有类型IO a -> IO (),还有一些初始化例程run

我正在尝试执行以下操作:

但在这种情况下 gui 必须有 type gui :: MApp AppGlobals。由于它的类型,不可能使用通常的 IO monad 语法,我的意思是我liftIO每次执行 IO 操作时都必须使用。

在 wxHaskell 中使用 State monad 是否有任何方便的可能性?手动将状态传递给每个事件处理程序并不是很方便。

0 投票
1 回答
688 浏览

haskell - 延续单子“接口”

状态单子“接口”

(+ return and bind) 允许在不使用State构造函数的情况下使用 State monad 构造任何可能的计算。例如,State $ \s -> (s+1, s-1)可以写成

同样,我永远不必使用Reader构造函数,因为我可以使用ask,return(>>=). 准确地说:Reader f == ask >>= return . f

延续是否也一样——是否可以编写所有Cont r a使用实例callCC(中唯一的函数MonadCont)、返回和绑定,并且从不输入类似的东西Cont (\c -> ...)

0 投票
4 回答
3324 浏览

haskell - Haskell:如何在 State monad 之上编写交互式解释器?

我们正在开发一个在内部使用状态单子的模型文件系统。我们有一个类型类,其操作如下:

我们正在开发一个小型交互式解释器,它将提供诸如cdls、等命令cat。解释器中的操作可以这样写:

Operation和的定义Response并不重要;如果你喜欢,把它们当作字符串。

我要解决的问题是在 I/O monad 中编写一个顶级循环来解释文件系统Operation并打印响应。如果 IO 是 FS 的一个实例(也就是说,如果我们直接使用 IO monad),生活会很简单:我们可以写

但这不是我想要的。我想使用Control.Monad.State

并声明

使用FS抽象,我可以编写一个可以与任何实例一起使用的单步函数,并且确实可以编译以下代码:

在这一点上,我完全被困住了。要做的是在 IO monad 中编写一个交互式循环,它可以读取Operations 和 print Responses,但它适用于不一定是 IO 的状态monad。(有一个不在 IO 中的模型的原因之一是我们可以测试 QuickCheck 属性。)

我觉得这必须是一个标准问题——在一个非有状态抽象之上的交互式读取 - 评估 - 打印循环- 但我一定遗漏了一些非常明显的东西,因为我似乎无法 IO弄清楚。我在网上看过,但没有开悟。

任何帮助编写可以调用的交互式、执行 IO 的计算step将不胜感激。

0 投票
2 回答
1234 浏览

haskell - 状态单子哈斯克尔

我想写一个函数来使用haskell中的State Monad计算平均值这是我写的代码

我在 GHCI 中编译时遇到了这个错误,我卡在那里你能帮我理解什么是错的,提前谢谢你