似乎关于并发访问的规则是未记录的(在Haskell方面)并且简单地假设开发人员熟悉正在使用的特定后端.对于生产需求而言,这是一个完全合理的假设,但对于随意的原型设计和开发,如果持久性*包更加自包含,那将会很好.
那么,管理对persistent-sqlite和family的并发访问的规则是什么?隐含地,如果我们有连接池,则必须允许某种程度的并发,但是通常创建单个连接池并且调用replicateM x $ forkIO (useThePool connectionPool)会产生以下错误.
user error (SQLite3 returned ErrorBusy while attempting to perform step.)
Run Code Online (Sandbox Code Playgroud)
编辑:现在下面是一些示例代码.
在下面的代码中,我分叉了6个线程(任意数字 - 我的实际应用程序执行3个线程).每个线程不断存储和查找记录(来自其他线程正在访问的记录的唯一记录,但这无关紧要),打印其中一个字段.
{-# LANGUAGE TemplateHaskell, QuasiQuotes
, TypeFamilies, FlexibleContexts, GADTs
, OverloadedStrings #-}
import Control.Concurrent (forkIO, threadDelay)
import Database.Persist
import Database.Persist.Sqlite hiding (get)
import Database.Persist.TH
import Control.Monad
import Control.Monad.IO.Class
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist|
SomeData
myId Int
myData Double
MyId myId
|]
main = withSqlitePool "TEST" 40 $ \pool -> do
runSqlPool (runMigration migrateAll) pool
mapM_ forkIO [runSqlPool …Run Code Online (Sandbox Code Playgroud) 我正在使用QuickCheck 1,我有以下数据类型:
data A = ...
instance Arbitrary A where ...
data B = ...
instance Arbitrary B where ...
data C = C A B
Run Code Online (Sandbox Code Playgroud)
现在,我想定义一个Arbitrary实例C,使C值是使用现有的发电机产生A和B.我最终这样做了:
instance Arbitrary C where
arbitrary = elements [(C a b) |
a <- generate 20 (System.Random.mkStdGen 0) arbitrary,
b <- generate 20 (System.Random.mkStdGen 0) arbitrary]
Run Code Online (Sandbox Code Playgroud)
这是明确生成固定数量的值A和B必要的,还是有更好的方法将现有的结合Arbitraries到一个新的?
出于性能原因,我希望将ByteString(严格的,现在的)零拷贝演绎到a Vector.由于Vector只是ByteArray#在引擎盖下,并ByteString是ForeignPtr这可能看起来是这样的:
caseBStoVector :: ByteString -> Vector a
caseBStoVector (BS fptr off len) =
withForeignPtr fptr $ \ptr -> do
let ptr' = plusPtr ptr off
p = alignPtr ptr' (alignment (undefined :: a))
barr = ptrToByteArray# p len -- I want this function, or something similar
barr' = ByteArray barr
alignI = minusPtr p ptr
size = (len-alignI) `div` sizeOf (undefined :: a)
return (Vector 0 size barr') …Run Code Online (Sandbox Code Playgroud) 我正在实现一个算法来计算C中的自然日志.
double taylor_ln(int z) {
double sum = 0.0;
double tmp = 1.0;
int i = 1;
while(tmp != 0.0) {
tmp = (1.0 / i) * (pow(((z - 1.0) / (z + 1.0)), i));
printf("(1.0 / %d) * (pow(((%d - 1.0) / (%d + 1.0)), %d)) = %f\n", i, z, z, i, tmp);
sum += tmp;
i += 2;
}
return sum * 2;
}
Run Code Online (Sandbox Code Playgroud)
如print语句所示,tmp最终确实等于0.0,但是循环继续.可能是什么导致了这个?
我在Fedora 14 amd64上并编译:
clang -lm -o taylor_ln taylor_ln.c
Run Code Online (Sandbox Code Playgroud)
例:
$ ./taylor_ln 2
(1.0 …Run Code Online (Sandbox Code Playgroud) 我想在Thunderbird的主窗口中显示之前修改一条消息.我似乎无法找到1)打开/查看新消息时将触发的事件2)修改消息显示内容的方法.
我相信我需要chrome://messenger/content/messenger.xul叠加层,并且可以使用如下的监听器:
window.addEventListener( "SOME MAGIC HERE", modify_message_handler, true );
Run Code Online (Sandbox Code Playgroud)
但是那个事件是什么,我不确定,还有我会得到什么对象(消息标题?)以及我可以轻松修改显示的内容.
所以问题是:
简单的问题.
这编译:
module Example where
import Network
port :: PortID
port = PortNumber 3001
Run Code Online (Sandbox Code Playgroud)
而这不是:
module Example where
import Network (PortID, PortNumber)
port :: PortID
port = PortNumber 3001
Run Code Online (Sandbox Code Playgroud)
GHC说:
Example.hs:6:8: Not in scope: data constructor `PortNumber'
Run Code Online (Sandbox Code Playgroud)
为什么?
对于下面的代码,我观察到非常快速的结果,似乎是由三个不寻常的方面引起/影响:
(set-option :produce-proof true),最终的UNSAT非常快.如果没有此选项,最终的check-sat不会终止.有人可以解释这些情况下的行为吗?只是选项的组合导致保留正确的事实来快速回答最终的SAT吗?未使用的构造函数的字段名称如何影响求解器的性能?
与此问题相关的代码如下.嵌入在代码中的是具有额外上下文和重复问题的注释.
;;;;;;;;;;;;;;;;;;;;;;;;;;;; Configuration ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; E-matching won't terminate on our queries, so turn it off
(set-option :smt.ematching false)
(set-option :smt.mbqi true)
;; In lieu of an initial test, produce-proofs true is a huge benefit to
;; the performance of the final check-sat
(set-option :produce-proofs true)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Raw data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Our syntactic representation of 'Bits'
;; Removing 'Raw2345', or renaming it to 'Raw2', causes ~30x more computation time.
(declare-datatypes …Run Code Online (Sandbox Code Playgroud) 通用编程时间!
如果我有一个功能:
f :: a1 -> a2 -> a3 -> ... -> an
Run Code Online (Sandbox Code Playgroud)
和一个价值
v :: aX -- where 1 <= x < n
Run Code Online (Sandbox Code Playgroud)
不知道在编译的时候,其中的参数f值v是正确的类型(如果有的话),我可以部分地适用f于v?(使用Typeable,Data,TH或任何其他技巧)
稍微坚定一点,我可以g在运行时构建函数(下面)吗?它实际上不必是多态的,我的所有类型都将是单态的!
g :: (a1 -> a2 -> a3 -> a4 -> a5) -> a3 -> (a1 -> a2 -> a4 -> a5)
g f v = \x y z -> f x y v z
Run Code Online (Sandbox Code Playgroud)
我知道,使用Typeable(typeRepArgs特别是),v是第三个参数f,但这并不意味着我有办法部分应用f.
我的代码可能看起来像: …
背景
在回答一个问题时,我构建并上传了一个有界tchan(我不适合上传jnb的版本).如果名称不够,则有界tchan(BTChan)是具有最大容量的STM信道(如果信道处于容量则写入块).
最近,我收到了添加像常规TChan一样的重复功能的请求.从而开始出现问题.
BTChan看起来如何
下面是BTChan的简化(实际上是非功能性)视图.
data BTChan a = BTChan
{ max :: Int
, count :: TVar Int
, channel :: TVar [(Int, a)]
, nrDups :: TVar Int
}
Run Code Online (Sandbox Code Playgroud)
每次你写入频道时,你都会nrDups在元组中包含dups()的数量- 这是一个'单个元素计数器',它表示有多少读者获得了这个元素.
每个读者都会减少它读取的元素的计数器,然后将它的读指针移动到列表中的下一个元素.如果读取器将计数器递减到零,count则递减值以正确反映通道上的可用容量.
要明确所需的语义:通道容量表示通道中排队的最大元素数.任何给定元素排队,直到每个dup的读者都收到该元素.没有元素应该保留为GCed dup排队(这是主要问题).
例如,让三个容量为2的通道(c1,c2,c3)重复,其中2个项目写入通道,然后所有项目都从c1和读出c2.频道仍然已满(0剩余容量),因为c3尚未使用其副本.在任何时间点,如果所有引用c3都被删除(因此c3是GCed),那么应该释放容量(在这种情况下恢复为2).
这是问题所在: 假设我有以下代码
c <- newBTChan 1
_ <- dupBTChan c -- This represents what would probably be …Run Code Online (Sandbox Code Playgroud) 我正在考虑在Coq中编写代码并提取此代码以用于大型Haskell项目.我想在Coq中构建一个单独的模块,证明属性,然后使用Haskell的模块系统来防止违反这些属性(通过智能构造函数).
我找不到任何迹象表明可以将Coq代码提取到具有显式导出列表的Haskell模块中.看来我必须手工修改提取的Coq代码,这不是什么大问题,但我想知道我是否有这个权利.有人有替代提案吗?
haskell ×6
c ×1
concurrency ×1
coq ×1
ghc ×1
javascript ×1
logarithm ×1
persistent ×1
quickcheck ×1
thunderbird ×1
yesod ×1
z3 ×1