这是关系到我的模块一个问题在这里,并简化了一下.它也与之前的问题有关,我在这个问题中过度简化了我的问题并没有得到我想要的答案.我希望这不是太具体,如果你能想到更好的话,请更改标题.
我的模块使用并发chan,分为读取侧和写入侧.我使用一个带有关联类型同义词的特殊类来支持多态通道"连接":
{-# LANGUAGE TypeFamilies #-}
class Sources s where
type Joined s
newJoinedChan :: IO (s, Messages (Joined s)) -- NOT EXPORTED
--output and input sides of channel:
data Messages a -- NOT EXPORTED
data Mailbox a
instance Sources (Mailbox a) where
type Joined (Mailbox a) = a
newJoinedChan = undefined
instance (Sources a, Sources b)=> Sources (a,b) where
type Joined (a,b) = (Joined a, Joined b)
newJoinedChan = undefined
-- and so on …Run Code Online (Sandbox Code Playgroud) 考虑以下:
do
x1 <- new 2
set x1 3
x2 <- get x1
y1 <- new 10
set y1 20
y2 <- get y1
return (x2 + y2)
Run Code Online (Sandbox Code Playgroud)
我想要这个结果23.有没有办法在纯Haskell中实现这样的东西,如果是这样的话怎么样?我理解STRef这样的事情,但我只是想在普通的Haskell中做到这一点(现在不担心效率).我认为我必须创建一个数据类型并使其成为实例Monad,但我不确定细节,所以一个有用的例子会有所帮助.
我试图了解如何将一些quickcheck测试与cabal集成.这个要点表明该quickCheck函数在失败时返回非零状态,但我没有得到这种行为,因此使用cabal的exitcode-stdio-1.0测试套件类型似乎对我不起作用,除非我想调用error我的所有测试.
cabal 用户指南还提到了一个detailed-1.0测试套件,但AFAICT还没有.那还是这样吗?
这似乎从类似的回答这一个,很多人都在使用测试框架封装.这对我来说太过分了,但这是我应该用的吗?
我对这种情况感到不满意.
我正在使用的东西的版本:
cabal-install version 0.10.2
using version 1.10.1.0 of the Cabal library
QuickCheck-2.4.1.1
Run Code Online (Sandbox Code Playgroud) 该文件说:
在并发程序中,IORef操作可能无序地出现在另一个线程上,具体取决于底层处理器体系结构的内存模型......需要实现以确保重新排序内存操作不会导致类型正确的代码进入错误.特别是,当检查从IORef读取的值时,内存写入创建该值必须从当前线程的角度发生.
我甚至不完全确定如何解析.爱德华杨说
换句话说,"我们不保证重新排序,除了你不会有任何类型安全违规."......最后一句话说明IORef不允许指向未初始化的内存
所以...它不会破坏整个哈希尔; 不是很有帮助.记忆模型例子的讨论也给我留下了问题(甚至Simon Marlow似乎有些惊讶).
从文档中我可以清楚地看到的事情
在一个线程中,atomicModifyIORef"永远不会在任何早期的IORef操作之前,或者在任何后来的IORef操作之后发生",即我们得到一个部分排序:在原子模块之上的东西 - >原子模型 - >之后的东西.虽然,这里的措辞"从未被观察到",但暗示了我没有预料到的怪异行为.
readIORef x之前可能会移动A writeIORef y,至少在没有数据依赖性时
从逻辑上讲,我没有看到类似的东西readIORef x >>= writeIORef y可以重新排序
有什么不清楚的
会newIORef False >>= \v-> writeIORef v True >> readIORef v永远回来True吗?
在maybePrint案件中(来自IORef文档)之前readIORef myRef(可能是一个seq或某个东西)readIORef yourRef会强制重新排序的障碍吗?
我应该有什么直截了当的心理模型?是这样的:
从单个线程的角度来看,IORef操作的顺序将显得健全和顺序; 但是编译器实际上可能以一种在并发系统中破坏某些假设的方式重新排序操作; 但是当一个线程执行时
atomicModifyIORef,没有线程会观察到之后IORef出现的操作atomicModifyIORef,反之亦然.
...?如果没有,上面的更正版本是什么?
如果你的回答是"不使用IORef的并行代码,使用TVar"请说服我用具体的事实和那种事情,你的具体例子不能与推理IORef.
这是一个后续我先前的问题在这里.我已经能够根据里德巴顿的答案得到一些工作,但我注意到核心我看到了__pkg_ccall_GC:
case {__pkg_ccall_GC hashabler-2.0.0 sipRound_s_x2 Word#
-> Word#
-> Word#
-> Word#
-> (# Word#, Word#, Word#, Word# #)}
ww1 ww2 ww3 (xor# ww4 b1)
Run Code Online (Sandbox Code Playgroud)
我认为你对"安全"ffi电话的期望是什么.然而,不允许在外部导入字符串中添加"unsafe"(尽管错误消息没有说明原因):
src/Data/Hashabler/SipHash.hs:60:1: error:
• The safe/unsafe annotation should not be used with `foreign import prim'.
• When checking declaration:
foreign import prim unsafe "static sipRound_s_x4" sipRound_s_x4#
:: Word#
-> Word# -> Word# -> Word# -> (# Word#, Word#, Word#, Word# #)
Run Code Online (Sandbox Code Playgroud)
我的外国程序只是一点点,但有点笨拙,所以我不认为我想要的_GC是什么.我看过GHC源的一些相关内容,FWIW和背景:
compiler/prelude/ForeignCall.hs:只有"Risky"省略了"_GC"
data Safety
= PlaySafe …Run Code Online (Sandbox Code Playgroud) 我想知道,如果在Haskell中有一个标准的,规范的方式,不仅要编写特定文件格式的解析器,还要编写一个编写器.
在我的例子中,我需要解析一个数据文件进行分析.但是,我还模拟要分析的数据并将其保存为相同的文件格式.我现在可以使用Parsec或类似的东西编写解析器,并编写以所需方式执行文本输出的函数,但每当我更改文件格式时,我都必须在代码中更改两个函数.有没有更好的方法来实现这一目标?
谢谢你,多米尼克
我的理解是,没有字段的类型的构造函数是"静态分配"的,GHC 在所有用途之间共享这些构造函数,并且GC不会移动它们.
如果这是正确的,那么我希望使用reallyUnsafePtrEquality#on值False和Nothing非常安全(没有错误否定或肯定),因为它们只能表示为与该构造函数的单个实例相同的指针.
我的推理是否正确?是否有任何潜在的问题或理由怀疑在不久的将来版本的GHC中这可能会变得不安全?
我该如何执行以下操作之一?
ThreadID从应用程序代码中获取所有正在运行的分叉线程(最好带有标签)的列表?gdb或类似处获得上述任何一项对我不起作用的事情:
我认为可能有希望的事情:
在Haskell中如何实现套接字,管道和文件IO等低级内容?我猜这些IO方法在Haskell中不是原生的,但是Haskell会快速包装一些低级C库,是不是?
我想将相同的数据分成两个"分支"进行单独处理,然后"加入"......
+----------+
+---------+ -->| doublber |--- +--------+
+--------+ | |-- +----------+ -->| | +------+
| source |-->| splitter| | summer |-->| sink |
+--------+ | |-- +----------+ -->| | +------+
+---------+ -->| delayer |--- +--------+
+----------+
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
我的尝试:
import Data.Conduit
import Control.Monad.IO.Class
import qualified Data.Conduit.List as CL
-- import Data.Conduit.Internal (zipSources)
import Control.Arrow ((>>>))
source :: Source IO Int
source = do
x <- liftIO $ getLine
yield (read x)
source
splitter :: Conduit Int IO (Int, Int)
splitter = …Run Code Online (Sandbox Code Playgroud) haskell ×10
ghc ×6
cabal ×1
concurrency ×1
conduit ×1
ffi ×1
file-writing ×1
generics ×1
hook ×1
ioref ×1
linux ×1
monads ×1
parsec ×1
parsing ×1
quickcheck ×1
runtime ×1
state-monad ×1