Stéphane Laurent
Stéphane Laurent

Reputation: 84529

How to poke two vectors?

I have a C function like this:

double* f(double* input, size_t n, double* result){
  for(int i=0; i<n; i++){
    result[i] = ***something***
  }
  return result;
}

I import it in Haskell like this (thanks to @Zeta):

{-# LANGUAGE ForeignFunctionInterface #-}
import qualified Data.Vector.Storable         as V
import           Foreign
import           Foreign.C.Types

foreign import ccall unsafe "f" c_f :: Ptr CDouble -> CSize -> Ptr CDouble -> IO (Ptr CDouble)

f :: V.Vector CDouble -> IO (V.Vector CDouble)
f input = do
    fptr <- mallocForeignPtrArray n
    V.unsafeWith input $
      \v -> withForeignPtr fptr $ c_f v (fromIntegral n)
    return $ V.unsafeFromForeignPtr0 fptr n
  where n = V.length input

Very nice.

But now I have a function taking two pointers as input:

double* f(double* input1, double* input2, size_t n, double* result){
  for(int i=0; i<n; i++){
    result[i] = ***something***
  }
  return result;
}

How can I import it to have f :: V.Vector CDouble -> V.Vector CDouble -> IO (V.Vector CDouble) ?

Perhaps it's easy but I'm still not comfortable with withForeignPtr.

Upvotes: 1

Views: 84

Answers (1)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

Simply:

f :: V.Vector CDouble -> V.Vector CDouble -> IO (V.Vector CDouble)
f input1 input2 = do
    fptr <- mallocForeignPtrArray n
    V.unsafeWith input1 $ 
      \v1 -> V.unsafeWith input2 $
        \v2 -> withForeignPtr fptr $ c_f v1 v2 (fromIntegral n)
    return $ V.unsafeFromForeignPtr0 fptr n
  where n = V.length input

Upvotes: 1

Related Questions