Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6987063
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T18:53:18+00:00 2026-05-27T18:53:18+00:00

I have a data structure of the form below (V is Data.Storable.Vector): data Elems

  • 0

I have a data structure of the form below (V is Data.Storable.Vector):

data Elems = I {-# UNPACK #-} !GHC.Int.Int32
             | S {-# UNPACK #-} !GHC.Int.Int32 {-# UNPACK #-} !(Ptr CChar)
             | T {-# UNPACK #-} !(V.Vector Elems)
                deriving (Show)

I first wrote a custom storable definition for non-recursive form (i.e., without T constructor). Then, I tried to add custom peek and poke definition for T using ForeignPtr and length information from Vector (code is below). The GHC compiler complains about Storable instance not being defined for ForeignPtr Elems type. My question is if it is possible to store ptr to Vector in Storable definition, without being forced to write Storable instance definition for ForeignPtr.

From Haddocs documentation, ForeignPtr seems to be just a Ptr with a Finalizer assigned to it:

The essential difference between ForeignPtrs and vanilla memory
references of type Ptr a is that the former may be associated with
finalizers.

I don’t want to work around the issue by using Ptr instead of ForeignPtr, because of issues of finalizing it. So, I prefer storing location of ForeignPtr (through Ptr (ForeignPtr a)) so that GHC garbage collector knows about the reference to it. But, that approach would force me to define a Storable instance (because of constraint (Storable a) => Ptr a which makes sense).

Is there a way to store and retrieve ptr to a Vector in Storable, without defining Storable instance for ForeignPtr? If there isn’t, then writing the Storable definition of ForeignPtr is a must. In that case, what would it look like? My guess is it will just store a Ptr to ForeignPtr.

The full code below:

{-# LANGUAGE MagicHash #-}
import qualified Data.Vector.Storable as V
import Foreign
import Foreign.C.Types (CChar)
import Foreign.Marshal.Array (lengthArray0)
import GHC.Int

data Elems = I {-# UNPACK #-} !GHC.Int.Int32
             | S {-# UNPACK #-} !GHC.Int.Int32 {-# UNPACK #-} !(Ptr CChar)
             | T {-# UNPACK #-} !(V.Vector Elems)
                deriving (Show)

instance Storable Elems where
  sizeOf _ = sizeOf (undefined :: Word8) + sizeOf (undefined :: Int32) + sizeOf (undefined :: Ptr CChar)
  alignment _ = 4

  {-# INLINE peek #-}
  peek p = do
      let p1 = (castPtr p::Ptr Word8) `plusPtr` 1 -- get pointer to start of the element. First byte is type of element
      t <- peek (castPtr p::Ptr Word8)
      case t of
        1 -> do 
          x <- peek (castPtr p1 :: Ptr GHC.Int.Int32) 
          return (I x)
        2 -> do 
          x <- peek (castPtr p1 :: Ptr GHC.Int.Int32) 
          y <- peek (castPtr (p1 `plusPtr` 4) :: Ptr (Ptr CChar)) -- increment pointer by 4 bytes first
          return (S x y)
        _ -> do
          x <- peek (castPtr p1 :: Ptr Int)
          y <- peek (castPtr (p1 `plusPtr` 8) :: Ptr (ForeignPtr Elems)) 
          return (T (V.unsafeFromForeignPtr y 0 x)) -- return vector

  {-# INLINE poke #-}
  poke p x = case x of
      I a -> do
        poke (castPtr p :: Ptr Word8) 1  
        poke (castPtr p1) a
      S a b -> do
        poke (castPtr p :: Ptr Word8) 2
        poke (castPtr p1) a
        poke (castPtr (p1 `plusPtr` 4)) b -- increment pointer by 4 bytes first
      T x -> do
        poke (castPtr p :: Ptr Word8) 3
        let (fp,_,n) = V.unsafeToForeignPtr x
        poke (castPtr p1) n
        poke (castPtr (p1 `plusPtr` 8)) fp

      where  p1 = (castPtr p :: Ptr Word8) `plusPtr` 1 -- get pointer to start of the element. First byte is type of element
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T18:53:19+00:00Added an answer on May 27, 2026 at 6:53 pm

    ForeignPtrs cannot be made Storable, because their implementation demands a way to associate one or many finalizer pointers to a raw pointer, and this association is runtime-dependent. To make the ForeignPtr storable, you need to store the associated Ptr (which is easy) and the array of associated finalizers (which is impossible, since the finalizers are runtime-internal, and might bind to the GC of the GHC runtime).

    This is not the problem that needs to be solved here, though.

    The problem is that there’s no reasonable way to make something that contains a Vector into something Storable. A Vector demands managed memory for its contents (The definition of Storable.Vector is data Vector a = Vector Int (ForeignPtr a) plus some strictness annotations), but the whole purpose of Storable is to store some value into unmanaged memory. Further, a Vector uses different amounts of memory depending on its length, but Storable data structures must use a constant amount of memory.

    You need to rethink what your data structure is trying to model. Do you really need to store a Vector like this? Remember that you are storing a Vector of Elems, meaning that you can have a value T that contains a Vector that contains a T that contains a Vector that contains a T, etc.

    I think that you might be trying to model the following data structure instead, but I might be wrong:

    data Elems = OneElem Elem | ManyElems (Vector Elem)
    
    data Elem
        = I !GHC.Int.Int32
        | S !GHC.Int.Int32 !(Ptr CChar)
    

    If you really need the recursive data structure that you described, try to implement this instead:

    data Elems
        = I !GHC.Int.Int32
        | S !GHC.Int.Int32 !(Ptr CChar)
        | T !GHC.Int.Int32 !(Ptr Elems)
    

    A pointer to some Elems uses constant memory, and can point to unmanaged memory, so you can create storable instances for it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a data structure where an entity has times stored as an int
I have a data structure which is as given below: class File { public
The end goal is to have some form of a data structure that stores
I have a Clojure data structure of the form: {:foo '(bar blat)} and have
I have a data structure that represents C# code like this: class Namespace: string
I have a data structure which uses composite ids (Which I dont wish to
I have a data structure defined as struct myDataStruct { int32_t header; int16_t data[8];
Guys, I have a data structure which has 25 distinct keys (integer) and a
I have the following data structure (a list of lists) [ ['4', '21', '1',
I have a tree data structure that is L levels deep each node has

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.