我收集实时信号,计算派生信号并将原始数据和派生数据存储在循环缓冲区中,因此我只保存最后一百万个样本。
有时我需要序列化所有信号的当前值。所以我需要类似的东西:
type D0 a = M.Map SignalType D1
data D1 a = D1
{ foo :: M.Map DoorType a
, bar :: D2 a
, baz :: a
}
data D2 = D2
{
quux :: a
, zoo :: a
}
data MyData = D0 SignalBuffer
data CurrentSignals = D0 SignalValue
SignalBuffer
是一个序列SignalValue
。它可以是一个未装箱的浮点数组。Haskell 可以Functor
为我派生实例,因此我可以使用从每个fmap
中获取最后一个并将结构传递给以进行序列化。SignalValue
SignalBuffer
Aeson
如何实现循环缓冲区 API,SignalBuffer
以便在新滴答到达时将新值推送到所有缓冲区?我想节省内存,所以我想我必须使用未装箱的数组。使用可变的未装箱数组(STUArray
?)是否有利,因此数组更新不会堆积在内存中?是否可以在此设置中使用可变数组?我已经准备好改变MyData
,CurrentSignals
无论做什么工作。
我知道如何实现循环缓冲区,问题是如何优雅地将更新应用于MyData
.
我在想类似的东西
type UpdateFunc a = MyData -> SignalValue -> Modifier SignalBuffer
updateAllBuffers :: D0 UpdateFunc -> Modifier MyData
一些信号是其他信号的“卷积”(不是真正的卷积,而是一种类似的处理)。要更新信号的缓冲区,我需要访问其他信号的缓冲区——这就是 UpdateFunc 接受MyData
并SignalValue
返回缓冲区修改函数的原因。
updateAllBuffers
然后“拉链”D0 UpdateFunc
并MyData
获得新的MyData
.
当然,我已经准备好使用Modifier
适合我任务的任何东西——它可以是一个函数、一个单子值等。