我有一种形式的数据类型:
data T = { a :: Int, b :: ComplexOtherDataType }
我显然可以将它们放入Data.Vector
模块的常规向量中。但是当我访问a
组件时,我想要非常非常好的性能,因此额外的间接是不可取的。我想要做的是让T
成为Data.Vector.Unboxed.Unbox
的实例,但仍有b
懒惰。
vector-th-unbox
为Unbox
的实例提供了一个很好的模板haskell接口,但在我的情况下它不起作用。为了使T
Unbox
的实例成为必需,a
和 b
都必须是实例。但我不想取消装箱b
。我希望它是盒装/懒惰的。
我的直觉说,克服这个障碍的最简单方法是提供一种类型
newtype LazyUnbox a = LazyUnbox a
然后,我需要为Unbox
提供一个LazyUnbox
实例,它基本上只是将指针存储在未装箱的向量中。我怎样才能做到这一点?或者完全有更好的方法吗?
答案 0 :(得分:10)
你怎么想象“将指针存储为unbox”(即机器字)值?据我所知,GHC运行时不允许获取指向托管结构的指针。
权衡解决方案是制作您自己的VG.Vector
实例,例如
data TVector = TVector (VU.Vector Int) (V.Vector ComplexOtherDataType)
instance VG.Vector TVector T where
basicUnsafeIndexM (TVector va vb) i = do
a <- basicUnsafeIndexM va i
b <- basicUnsafeIndexM vb i
return (T a b)
...
您可以在需要时提取未装箱的部分VU.Vector Int
。
答案 1 :(得分:1)
Edward Kmett写了一篇文章解释如何做到这一点:
https://www.fpcomplete.com/user/edwardk/revisiting-matrix-multiplication/part-3
我无法理解为什么第二个字段在他的代码中保持盒装,但我确信它有效。它是hybrid-vectors
包。