Peter Simons wrote:
[[Int]] to int[][]
Pardon me if I'm telling you something you already know, but I wanted to make sure you are aware of it.
int[][] is a very different type than [[Int]] is. An int[][] is a pointer to an array of pointers to integers:
No it isn't; it's an array of arrays of integers. As C passes arrays by reference rather than value, it will be passed as a pointer to arrays of integers. However, you can't use "int[][]" directly as a type; all dimensions other than the first must be specified. E.g. "int [][4]" is an array of arrays-of-length-4 of integers, and will be passed as a pointer to arrays-of-length-4 of integers (i.e. incrementing the pointer will increment by 4*sizeof(int) bytes). Consequently, you can't directly use withArray, as that only works on lists whose elements are members of the Storable class, and lists aren't themselves members of Storable. To marshall such a list, one approach would be to simply flatten the list with concat, i.e.: withArray2D :: (Storable a) => [[a]] -> (Ptr a -> IO b) -> IO b withArray2D xs f = withArray (concat xs) f So long as all of the sublists are of the same length, this will do the right thing. If the sublists are of differing length, you would first need to either truncate or pad them to the same length, e.g.: withArray2D :: (Storable a) => [[a]] -> (Ptr a -> IO b) -> IO b withArray2D xs f = withArray xs' f where xs' = concat $ map (take dim) xs dim = minimum $ map length xs Padding is slightly more complex, as you have to choose a value with which to pad. -- Glynn Clements <glynn@gclements.plus.com>