<p><br>
On Jun 19, 2012 12:16 AM, &quot;Henning Thielemann&quot; &lt;<a href="mailto:lemming@henning-thielemann.de">lemming@henning-thielemann.de</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; On Mon, 18 Jun 2012, Roman Leshchinskiy wrote:<br>
&gt;<br>
&gt;&gt; There are type families, rank-n types, unboxed types and other goodies deep in the guts of vector so the Storable part is very much GHC-specific. To be honest, I don&#39;t think being portable is feasible for high-performance code at the moment, the language standard simply doesn&#39;t have enough tools for this. Which is a shame, really.<br>

&gt;<br>
&gt;<br>
&gt; I am not mainly interested in the efficient implementation. I am completely ok with having the definition of (Vector a) in a separate package, such that it can be used by vector (GHC only) and storablevector (portable).<br>

&gt;<br>
&gt; However, I have just looked into Vector.Storable and it looks like<br>
&gt;<br>
&gt;  data Vector a = Vector Int (ForeignPtr a)<br>
&gt;<br>
&gt; I thought it was<br>
&gt;<br>
&gt;  data Vector a = Vector {len :: Int, allocated :: ForeignPtr a, start :: Ptr a}<br>
&gt;<br>
&gt; ByteString looks like:<br>
&gt;<br>
&gt;  data ByteString = PS {allocated :: ForeignPtr Word8, start, length :: Int}<br>
&gt;<br>
&gt; Both forms allow efficient slicing.<br>
&gt; How do you perform efficient &#39;take&#39; and &#39;drop&#39; ?</p>
<p>Slicing is done by directly updating the pointer in the ForeignPtr:</p>
<p>{-# INLINE basicUnsafeSlice #-}<br>
basicUnsafeSlice i n (Vector _ fp) = <br>
    Vector n (updPtr (`advancePtr` i) fp)</p>
<p>{-# INLINE updPtr #-}<br>
updPtr :: (Ptr a -&gt; Ptr a) -&gt; ForeignPtr a -&gt; ForeignPtr a<br>
updPtr f (ForeignPtr p c) = <br>
    case f (Ptr p) of { Ptr q -&gt; ForeignPtr q c }</p>
<p>This saves an Int.</p>
<p>Regards,</p>
<p>Bas</p>