如何在inline-ec中使用Haskell数组



向量有一个ContextvecCtx,它允许从C代码访问Haskellvector

我需要使用多维数组,所以vector不适合我。我更喜欢使用array。但它没有Context。人们是否仍然可以以某种方式使用数组,或者他们是否为数组创建了一个特殊的上下文?

您可以为StorableArray创建一个实例,如下所示:

{-# 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

注意,这里使用unsafePerformIO是安全的,因为getBounds实际上是StorableArray的纯函数。array包中没有不可变的可存储数组,因此您有点陷入了一个可变的世界,考虑到您的目标是与C.接口,这可能很好

话虽如此,我强烈建议您查看用于处理多维数组的库(称为massiv(。如果您尝试过,下面是如何为大量可存储的可变和不可变数组创建VecCtx实例:

{-# 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

最新更新