Take the 2-minute tour ×

I have a data type of the form:

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

I can obviously put these into regular vectors from the Data.Vector module. But I want really, really good performance when I access the a component, so the extra indirection is undesirable. What I want to do is make T an instance of Data.Vector.Unboxed.Unbox, but still have b be lazy.

The vector-th-unbox provides a nice template haskell interface for making instances of Unbox, but it won't work in my case. It requires that in order to make T an instance of Unbox, both a and b must also be instances. But I don't want to unbox b. I want it to be boxed/lazy.

My intuition says that the easiest way to overcome this obstacle is by providing a type

newtype LazyUnbox a = LazyUnbox a

Then, I need to provide an Unbox instance for LazyUnbox that will basically just store a pointer inside the unboxed vector. How can I do this? Or is there a better approach entirely?

share|improve this question
Storable vectors have just as good performance and strictness properties as Unboxed vectors, so if you can make your datatype T implement Storable then you are good to go. –  Gabriel Gonzalez Jun 24 '13 at 4:27
add comment

1 Answer

up vote 7 down vote accepted

How do you imagine "storing a pointer as unbox" (i. e. machine word) value? GHC runtime don't allow to obtain pointers to managed structures, as far as I know.

A tradeoff solution is making your own VG.Vector instance, ex.

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)

You can extract unboxed part VU.Vector Int when needed.

share|improve this answer
add comment

Your Answer


