How do I create a Storable instance for a recursive type?

How do I create a Storable instance for a recursive type?

By : Nuno Cordeiro
Date : October 17 2020, 03:08 PM
I wish this help you You can’t have a Storable for this. These datatypes need to have a fixed size, just like C structs. Also, note that sizeof isn’t supposed to inspect the value you give it. It’s just a proxy/carrier for the type argument, so you can write e.g. sizeof (undefined::Int). Maybe take a look at Foreign.Marshal.Array
code :

Share : facebook icon twitter icon
Defining Storable for Recursive Data Structure Involving Vectors

Defining Storable for Recursive Data Structure Involving Vectors

By : user3919476
Date : March 29 2020, 07:55 AM
With these it helps 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.
code :
data Elems = OneElem Elem | ManyElems (Vector Elem)

data Elem
    = I !GHC.Int.Int32
    | S !GHC.Int.Int32 !(Ptr CChar)
data Elems
    = I !GHC.Int.Int32
    | S !GHC.Int.Int32 !(Ptr CChar)
    | T !GHC.Int.Int32 !(Ptr Elems)
FFI, trouble to make Storable instance

FFI, trouble to make Storable instance

Date : March 29 2020, 07:55 AM
To fix this issue You can make a Storable instance for ConnGraph, but it's a bit dodgy. The usual pattern is to malloc space for an array and marshal to that. However, since you know the max size, and space is allocated in the struct, you can take advantage of this and write:
code :
newtype ConnGraph = ConnGraph {unConnGraph :: [CShort]}

instance Storable ConnGraph where
    sizeOf _ = maxval*sizeOf (undefined :: CShort)
    alignment _ = alignment (undefined :: CShort)
    poke ptr (ConnGraph lst) = if length lst <= maxval
        then pokeArray (castPtr ptr) lst
        else error "Can't poke ConnGraph, too big!"
pokeArray (ptr `plusPtr` (#offset inchi_Atom, neighbor)) $ unConnGraph atoms'
-- I don't know how to do CPP in hsc2hs-generated Haskell, but you could create a separate module
-- that defines maxval = MAXVAL
maxval = 20

instance Storable INCHIAtom where
    sizeOf    _ = (#size inchi_Atom)
    alignment _ = alignment (undefined :: CDouble)
    peek _ = error "peek is not implemented"
    poke ptr (INCHIAtom atoms' label' bondType' charge') =
          (#poke inchi_Atom, x) ptr $ (0 ::CDouble)
          (#poke inchi_Atom, y) ptr $ (0 ::CDouble)
          (#poke inchi_Atom, z) ptr $ (0 ::CDouble)
          (#poke inchi_Atom, neighbor) ptr $ atoms'
          (#poke inchi_Atom, bond_type) ptr $ bondType'
          (#poke inchi_Atom, bond_stereo) ptr $ ConnGraph (replicate maxval 0)
          (#poke inchi_Atom, elname) ptr $ label'
          (#poke inchi_Atom, num_bonds) ptr $ (length $ unConnGraph atoms')
          (#poke inchi_Atom, num_iso_H) ptr $ (0 :: CSChar)
          (#poke inchi_Atom, isotopic_mass) ptr $ (0 :: CShort)
          (#poke inchi_Atom, radical) ptr $ (0 :: CSChar)
          (#poke inchi_Atom, charge) ptr $ charge'
Storable instance of Maybe

Storable instance of Maybe

By : user2244147
Date : March 29 2020, 07:55 AM
With these it helps Here's a potential instance, available on School of Haskell. The idea is to store an extra byte containing either a 0 or 1, indicating whether the value exists or not.
There are certainly more efficient approaches for individual Storable instance. For example, a Maybe Bool could be stored in a single byte instead of two bytes. But I don't think you can avoid the 1-byte overhead in the general case.
code :
instance Storable a => Storable (Maybe a) where
    sizeOf x = sizeOf (stripMaybe x) + 1
    alignment x = alignment (stripMaybe x)
    peek ptr = do
        filled <- peekByteOff ptr $ sizeOf $ stripMaybe $ stripPtr ptr
        if filled == (1 :: Word8)
            then do
                x <- peek $ stripMaybePtr ptr
                return $ Just x
            else return Nothing
    poke ptr Nothing = pokeByteOff ptr (sizeOf $ stripMaybe $ stripPtr ptr) (0 :: Word8)
    poke ptr (Just a) = do
        poke (stripMaybePtr ptr) a
        pokeByteOff ptr (sizeOf a) (1 :: Word8)
How do I create a Storable instance for this type?

How do I create a Storable instance for this type?

By : user3506225
Date : March 29 2020, 07:55 AM
With these it helps Ready (the C type) is not a struct or a union, it's a pointer to a struct _Ready. You should use struct _Ready instead, like
code :
peek p = Ready <$> (#peek struct _Ready, ready) p
poke p (Ready r) = (#poke struct _Ready, ready) p r
How do I create a storable instance for this structure without c2hs or other tools?

How do I create a storable instance for this structure without c2hs or other tools?

By : user3723351
Date : March 29 2020, 07:55 AM
hope this fix your issue I can't currently guarantee that this will work exactly as shown (I don't have the environment set up on this computer), but it should be a good first step towards getting it right:
code :
import Foreign.Storable
import Foreign.Ptr

instance Storable Atom where
    -- Don't make this static, let the compiler choose depending
    -- on the platform
    sizeOf _ = 3 * sizeOf (0 :: Float) + sizeOf (0 :: Int)
    -- You may need to fiddle with this, and with your corresponding C
    -- code if you have the ability to, alignment can be tricky, but
    -- in this case you can pretty safely assume it'll be the alignment
    -- for `Float`
    alignment _ = alignment (0 :: Float)
    -- These are pretty straightforward, and obviously order matters here
    -- a great deal.  I clearly haven't made this the most optimized it
    -- could be, I'm going for clarity of code instead
    peek ptr = do
        let floatSize = sizeOf (0 :: Float)
        x   <- peek $ ptr `plusPtr` (0 * floatSize)
        y   <- peek $ ptr `plusPtr` (1 * floatSize)
        z   <- peek $ ptr `plusPtr` (2 * floatSize)
        col <- peek $ ptr `plusPtr` (3 * floatSize)
        return $ Atom (V3 x y z) col
    poke ptr (Atom (V3 x y z) col) = do
        let floatSize = sizeOf (0 :: Float)
        poke (ptr `plusPtr` (0 * floatSize)) x
        poke (ptr `plusPtr` (1 * floatSize)) y
        poke (ptr `plusPtr` (2 * floatSize)) z
        poke (ptr `plusPtr` (3 * floatSize)) col
Related Posts Related Posts :
  • Pass string macro into C program - cross-platform
  • Function as parameter to function
  • reading&input data to 2d char array, and printf. in c
  • Client-side not creating file
  • Array and type/value errors in sorting function
  • What's wrong with this C program?I's always appear a new number we not input?Compiled with Dev-C++
  • Expected expression before
  • Stack structure pointing to itself - What's going on here?
  • compile tor on centos6. Problems with libevent
  • MIPS nested function calls
  • C undefined behavior. Strict aliasing rule, or incorrect alignment?
  • Why does the last code returns such result? (in C)
  • How to pass multiples arguments to thread in c? [Segmentation fault]
  • C Two structs cause segmentation fault 11
  • MPI_Reduce() program getting segmentation fault
  • How does the pthread_cond_wait() actually work?
  • strtok() function is tokenizing the string incorrectly
  • atan2f vs fmodf vs just plain subtraction
  • C reading file into 2D array
  • How to use recursion to determine if path exists between two nodes in graph?
  • SQLite: trouble building FTS5 loadable extension
  • Common words check loop doesn't work
  • How to get Mouse input inside a C console program on Windows-10?
  • Prevent external calls to functions inside lib file
  • Both struct variables getting same value inside union
  • instructions after scanf() call get called twice
  • Is it possible to override SSH expecting password input from /dev/tty in C
  • Assigning reference of variable to pointer results in unintended behavior
  • Is it safe to swap values of an unknown type
  • Defining something to itself in C preprocessor
  • Leibniz function in c
  • Why do major compilers use typedef for stdint.h but use #define for stdbool.h?
  • Using long double in C gives weird results after subtraction
  • Code seems to continue running after return statement (in C)
  • C Program Works in GDB But Not Normally
  • Trying to get a variable equal to other variables in C
  • Converting Arraylist implementation to universal in C
  • Segmentation Fault in using a node struct
  • How can I copy a dialogs position coordinates into another dialogs?
  • Why does gcc produce different compiled binaries for programs that use different forms of integer literals?
  • Program in c that takes an array and prints out and then finds its mean max and min. Not working properly
  • Unable to assign structure variable to another structure variable
  • Metamorphic Example Code
  • GCC vs Clang copying struct flexible array member
  • 2nd char array overwriting 1st char array after fread from file
  • Not getting all results shifting my array
  • Sysmalloc: Assertion
  • Hungarian Algorithm - Wikipedia method doesn't work for this example
  • Premultiplying image alpha efficiently
  • General Fibonacci, why is it overflowing?
  • shadow
    Privacy Policy - Terms - Contact Us © soohba.com