Home > Enterprise >  How to work with Haskell Array in inline-c
How to work with Haskell Array in inline-c

Time:11-05

There's a Context for vectors: vecCtx which allows access to Haskell vector from C code.

I need to work with multi-dimentional arrays so vector doesn't cut for me. I prefer to use array. But there isn't a Context for it. Do people somehow can still work with arrays or do they create a special context for arrays?

CodePudding user response:

You can create an instance for a StorableArray like so:

{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Array where

import Data.Array.Storable
import Foreign.Storable (Storable)
import Language.C.Inline.Context
import System.IO.Unsafe (unsafePerformIO)

instance (Ix ix, Storable e) => VecCtx (StorableArray ix e) where
  type VecCtxScalar (StorableArray ix e) = e
  vecCtxLength = rangeSize . unsafePerformIO . getBounds
  vecCtxUnsafeWith = withStorableArray

Note that it is safe to use unsafePerformIO here because getBounds is really a pure function underneath for StorableArray. There is no immutable storable array in array package, so you are sort of stuck in a mutable world with it, which might be fine, considering that your goal is to interface with C.

That being said, I highly recommend checking out library for dealing with multi-dimensional arrays that's called massiv. In case you do give it a try, here is how to create VecCtx instance for massiv storable mutable and immutable arrays:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Massiv where

import Data.Massiv.Array
import Data.Massiv.Array.Unsafe (unsafeWithPtr)
import Language.C.Inline.Context

instance (Index ix, Storable e) => VecCtx (Array S ix e) where
  type VecCtxScalar (Array S ix e) = e
  vecCtxLength = totalElem . size
  vecCtxUnsafeWith = unsafeWithPtr

instance (Index ix, Storable e) => VecCtx (MArray RealWorld S ix e) where
  type VecCtxScalar (MArray RealWorld S ix e) = e
  vecCtxLength = totalElem . sizeOfMArray
  vecCtxUnsafeWith = withPtr
  • Related