部分未装箱的载体

时间:2013-06-24 02:55:26

标签: haskell vector lazy-evaluation

我有一种形式的数据类型:

data T = { a :: Int, b :: ComplexOtherDataType }

我显然可以将它们放入Data.Vector模块的常规向量中。但是当我访问a组件时,我想要非常非常好的性能,因此额外的间接是不可取的。我想要做的是让T成为Data.Vector.Unboxed.Unbox的实例,但仍有b懒惰。

vector-th-unboxUnbox的实例提供了一个很好的模板haskell接口,但在我的情况下它不起作用。为了使T Unbox的实例成为必需,a b都必须是实例。但我不想取消装箱b。我希望它是盒装/懒惰的。

我的直觉说,克服这个障碍的最简单方法是提供一种类型

newtype LazyUnbox a = LazyUnbox a

然后,我需要为Unbox提供一个LazyUnbox实例,它基本上只是将指针存储在未装箱的向量中。我怎样才能做到这一点?或者完全有更好的方法吗?

2 个答案:

答案 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包。