# Call a Haskell DLL from Mathematica

Looking for a way to call a Haskell DLL from Mathematica, I've stumbled on this, for GNU R:

It is (to me) a beautiful example and I managed to make it work on Mathematica without modification through this spell:

Needs["NETLink"]
hsStart = DefineDLLFunction["HsStart", "c:\\temp\\SumRoots.dll", "void", {}];
hsEnd = DefineDLLFunction["HsEnd", "c:\\temp\\SumRoots.dll", "void", {}];
sroot = DefineDLLFunction["sumRootsR", "c:\\temp\\SumRoots.dll", "double", {"int*", "double[]", "double*"}];
hsStart[];
resulta = 0;
lista = {9, 3.5, 5.58, 64.1, 12.54};
sroot[Length[lista], lista, resulta];
resulta
18.7805
hsEnd[];


Then I tried to modify the example to return a vector of doubles, instead of a single value:

-- SumRoots.hs

{-# LANGUAGE ForeignFunctionInterface #-}
module SumRoots where

import Foreign

foreign export ccall acumSumR :: Ptr Int -> Ptr Double -> Ptr Double -> IO ()

acumSum :: [Double] -> [Double]
acumSum xs = scanl (\x y -> x+y) 0 xs

acumSumR :: Ptr Int -> Ptr Double -> Ptr Double -> IO ()
acumSumR n xs result = do
n <- peek n
xs <- peekArray n xs
pokeArray result $acumSum xs  Code in C: (exactly the same of the mentioned blog post) Compiling: ghc -c SumRoots.hs ghc -c StartEnd.c ghc -shared -o SumRoots.dll SumRoots.o StartEnd.o  Code in Mathematica: Needs["NETLink"] hsStart = DefineDLLFunction["HsStart", "c:\\temp\\SumRoots.dll", "void", {}]; hsEnd = DefineDLLFunction["HsEnd", "c:\\temp\\SumRoots.dll", "void", {}]; acums = DefineDLLFunction["acumSumR", "c:\\temp\\SumRoots.dll", "double[]", {"int*", "double[]", "double[]"}]; hsStart[]; lista = {9, 3.5, 5.58, 64.1, 12.54}; NETBlock@Module[{n, resultb}, n = Length[lista]+1; resultb = NETNew["System.Double[]", n]; acums[n, lista, resultb]; NETObjectToExpression[resultb]] {0., 0., 0., 0., 0., 0.}  The result should be {0.0, 9.0, 12.5, 18.08, 82.18, 94.72}. I'm not sure if this problem belongs to Mathematica or Haskell realm, but posting here is based on the fact that the GNU R call worked: dyn.load("C:/temp/SumRoots.dll") .C("HsStart") acumSum <- function(input) { return(.C("acumSumR", n=as.integer(length(input)), xs=as.double(input), result=as.double(rep(0,length(input)+1)))$result)
}
input <- c(9,3.5,5.58,64.1,12.54)
acumSum(input)


So, can somebody give a hint on how to call this modified Haskell DLL function from Mathematica?
Environment:
SO: Windows 10 64-bit
Mathematica 8.0 64-bit
GNU R 3.3.2 64-bit

Cheers,

Rand

The problem lies in the declaration of the DLL function acumSumR. It is declared to return a double[] but the Haskell return type is IO () which corresponds to C void. So the declaration should read:

acums =
DefineDLLFunction["acumSumR"
, "c:\\temp\\SumRoots.dll"
, "void"                           (* <-- "void" instead of "double[]" *)
, {"int*", "double[]", "double[]"}
];


With this change, the expected result is obtained.

• I Copy-Pasted your code to mine, however the result was the same. Could it be a configuration problem? Or maybe another way to call the acums function?
– rand
Jan 8, 2017 at 15:17
• I called acums using the code you exhibit. For me, both V8 and V11 give the same results: all zeros with double[] and the expected results for void. With double[] I also get a .NET exception complaining about invalid marshalling. Do you see that exception? I also get the same results (including warning message) whether I use .NET 2.0 or 4.6. I am on Win7 instead of Win10, but otherwise I am using the same versions as you. Jan 8, 2017 at 19:45