How can I get a list or array from C block in Haskell's inline-c? In other words, how to construct complex data in C and work with it in Haskell. Something like this:
foo :: IO [Int]
foo = do
what? <- [C.block| <what?> {
ints = calloc(10, sizeof(int));
// ...
return <what?>;
} |]
return <what?>
I could wrap a pointer and a size in some Haskell type, but I'd like to work with the list in Haskell, print it, encode in JSON, etc.
Return a pointer to the array from your C code and use peekArray
to marshal it to a list.
import Foreign.Marshal.Array
import Language.C.Inline
foo :: Int -> IO [Int]
foo size = [exp| int* { calloc($(int size), sizeof(int)) }] >>= peekArray size
peekArray
accepts a pointer argument and a number of elements to read. It iteratively increments the pointer size
times, pulling elements off the array using the type's Storable
instance (in this case, Int
).
It may be more efficient to turn your array into an unboxed Vector
.