Looking for a way to call a Haskell DLL from Mathematica, I've stumbled on this, for GNU R:
http://neilmitchell.blogspot.com.br/2011/10/calling-haskell-from-r.html
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:
Code in Haskell:
-- 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
Haskell Platform 8.0.1 64-bit
GNU R 3.3.2 64-bit
Cheers,
Rand