问题标签 [ioref]
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.
haskell - Haskell IORef 数组的使用
我正在开发一个使用大量IORef
's 到数据类型的程序。这是执行此操作的内存/处理器效率更高的方法:
或者
忽略我使用列表而不是向量或数组的事实。
haskell - 并发程序中IORef操作重排序的推理
文档说:
在并发程序中,IORef 操作对于另一个线程可能会出现乱序,具体取决于底层处理器架构的内存模型......需要实现以确保内存操作的重新排序不会导致类型正确的代码走错误的。特别是,在检查从 IORef 读取的值时,从当前线程的角度来看,创建该值的内存写入必须发生。
我什至不完全确定如何解析。爱德华杨说
换句话说,“我们不保证重新排序,除非你不会有任何类型安全违规。” ...最后一句指出不允许 IORef 指向未初始化的内存
所以......它不会破坏整个haskell;不是很有帮助。引发内存模型示例的讨论也给我留下了一些问题(即使是 Simon Marlow 也似乎有点惊讶)。
从文档中我觉得很清楚的事情
在线程中,
atomicModifyIORef
“从未观察到在任何早期的 IORef 操作之前或在任何以后的 IORef 操作之后发生”,即我们得到以下部分排序:原子模式之上的东西 -> 原子模式 -> 之后的东西。虽然,这里的“从未观察到”一词暗示了我没有预料到的怪异行为。readIORef x
之前可能会移动AwriteIORef y
,至少在没有数据依赖关系的情况下是这样。从逻辑上讲,我看不出如何
readIORef x >>= writeIORef y
重新排序
我不清楚什么
会
newIORef False >>= \v-> writeIORef v True >> readIORef v
一直回来True
吗?在这种
maybePrint
情况下(来自 IORef 文档),areadIORef myRef
(可能与 aseq
或其他东西一起)之前readIORef yourRef
是否会强制阻碍重新排序?
我应该有什么直截了当的心智模型?是不是像:
在单个线程内部和从单个线程的角度来看,IORef 操作的顺序将显得合理且连续;但编译器实际上可能会以打破并发系统中某些假设的方式重新排序操作;然而,当一个线程这样做时
atomicModifyIORef
,没有线程会观察到IORef
出现在上面的操作atomicModifyIORef
之后发生的操作,反之亦然。
...?如果不是,上面的更正版本是什么?
如果您的回答是“不要IORef
在并发代码中使用;请使用TVar
”,请用具体事实和具体示例来说服我,这些事情是您无法推理的IORef
。
variables - 简单的 Haskell IORef - “无法将类型 `IO Int' 与 `Int' 匹配” - 看不出它有何不同
我现在正在尝试使用 IORef 在 Haskell 中创建一个简单的随机数生成器来存储可变变量。这个想法是我可以初始化种子,然后根据种子生成数字,并将新种子存储为下一个随机整数。
我得到的完整错误是:
我不明白它为什么不能匹配类型 - 我明确表示 randomGen 需要/返回一个 Int。这是我的代码:
知道这里发生了什么吗?
谢谢,
更新代码:
performance - Haskell:IORefs 的性能
我一直在尝试在 Haskell 中编码一个需要使用大量可变引用的算法,但与纯粹的惰性代码相比,它(也许并不奇怪)非常慢。考虑一个非常简单的例子:
在我的机器上运行 GHC 7.8.2,main1
耗时 1.2 秒,使用 290MB 内存,而main2
仅耗时 0.4 秒,仅使用 1MB。有什么技巧可以防止这种增长,尤其是在太空中?我经常需要IORef
s 来表示与 不同的非原始类型Int
,并假设 anIORef
会像常规 thunk 一样使用附加指针,但我的直觉似乎是错误的。
我已经尝试过使用 unpacked 的特殊列表类型IORef
,但没有显着差异。
haskell - 如何将 IORef 与镜头一起使用?
想知道如何最好地将Control.Lens包与IORef
s 结合起来。具体来说,我希望能够atomicModifyIORef
与镜头一起使用,这样我就可以提供一个类型的函数a -> (a, b)
并从操作中返回一个值。代码片段:
haskell - 使用 IORef 与使用 Control.Monad.Trans.Control
我希望能够检查我的应用程序在通过Network.HTTP.Client
.
该功能未内置Network.HTTP.Client
,尽管文档中有一些对该想法的引用,包括(非工作)示例代码。似乎可以通过重用几乎完全现有的部分来完成,所以我决定尝试一下。
在进行一些谷歌搜索时,听起来Control.Monad.Trans.Control
可能可以满足我在堆栈中累积请求的需要StateT [Request] IO
,但是,在尝试了几天没有成功之后,我意识到如果我可以更轻松地做我想做的事我只是使用了一个IORef
--- 但我仍然很好奇我是否错过了一些聪明的方法来做到这一点而不诉诸可变性。
我的工作,IORef
基于 - 的例程看起来像:
我的非工作(因为它不累积请求),Control.Monad.Trans.Control
基于例程看起来像:
正如我所看到的,问题是我无法从handleRedirects
函数返回更新的状态,因为这是从内部调用的httpRedirect
——因此,我永远没有机会在更新的值上使用 restoreM 。我没有看到如何成功地结合这些东西,但我怀疑这只是我的想象力或理解力的失败。
为了使事情尽可能简单,这里有一个可以用于每个版本的测试工具:
haskell - 分叉的 IORef 读取器函数似乎停止了主线程
我正在做一些关于并发性和内存可见性的实验,并遇到了这种奇怪的行为(见内联评论):
我期待writeIORef
子线程可能不可见,但主线程不会简单地(显然)停止。
在 ghc 7.8.3 上编译
并运行
这里发生了什么事?
编辑:所以我的机器有两个真正的核心和两个超线程核心,所以使用+RTS -N
GHC 可以看到 4 个功能。根据 Gabriel Gonzalez 的回答,我尝试了以下方法,看看调度程序是否将两个线程放在同一个物理处理器上:
haskell - 在三便士 gui 中使用 IORef
我正在尝试在threepenny-gui 中设置一个IORef,但我无法让它工作。在我的应用程序中, IORef 本身会更复杂,并且不会显示 - 但这个例子展示了我认为的问题。
这是我的尝试:
代码有点工作,但 outValue 不是最新的。
如何修复它以便按时更新。此外,欢迎对代码进行任何改进。
谢谢。
scala - IORef 的用例是否正确?
目标是让人们输入一个整数,并验证它确实是一个整数。如果不是 - 然后再问。第一次尝试是使用ioMonad.whileM,因为它实际上在 IO 中返回值,并编写类似的东西(然后我们可以“安全地”将 String 转换为 Int):
但是这种方法没有奏效,因为在这种情况下,我不仅要验证值,还要再次从控制台读取它。
因此,由于我需要读取输入,然后以某种方式将其传递给条件,所以我在想,IORef可能是完全正确的工具(我以前从未使用过它,所以将此视为我学习函数式编程的卑微尝试) . 我结束了:
发生的事情是 - 实际上整个循环被完全忽略了,程序直接进入带有初始 ref 的行:
那么,我在这里滥用Ref概念吗?为什么它不起作用?
谢谢
更新: 实际上我通过编写这个方法解决了最初的问题:
接着whileMpropagating(askAndReadNumber)(_ forall notDigit)(ioMonad) map (_.toInt)
但我仍然有兴趣在这里使用 IORef。
Update2:我的耻辱,iterateWhile
在 Monad 中确实如此 :)
haskell - 在 Haste 中为 StateT monad 编写区间函数
所以我编写了自己的实现,StateT
因为我无法让转换器在 Haste 中正确编译。我想想让 javascriptsetInterval
在我的状态 monad 中工作。这是对 ffi 的调用setInterval
。
无论如何,我都想不到m
在它传递给jsInterval
. 所以我尝试使用IORefs
.
这不起作用,因为它保持了原始状态。读发生在写之前。所以我写了一个函数,它会在一个循环中轮询直到IORef
写完,但这只是永远挂起。
有没有可能实现这个功能?MonadEvent
我尝试编写一个for的实例,StateT
但这也没有成功。