FFI is Haskell's Foreign Function Interface and allows interoperability with other languages, e.g., calling into a C library from Haskell or using your Haskell module from a C program. For more examples, see the FFI cookbook.
GHC's interactive environment, invoked with ghci, evaluates Haskell code in a REPL, loads and runs compiled modules, and provides familiar debugger functionality such as stepping, tracing, and catching exceptions.
Consider the following simple Haskell program that comprises two modules:
module Main where | |
import Message | |
main :: IO () | |
main = putStrLn message |
module Message (message) where | |
message = "Hello, world!" |
$ ghci hello.hs GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 2] Compiling Message ( Message.hs, interpreted ) [2 of 2] Compiling Main ( hello.hs, interpreted ) Ok, modules loaded: Main, Message. *Main> main Hello, world!(If you're invoking ghci from Cygwin, you'll want to use ghcii.sh.)
With FFI, you have to hold ghci's hand a little. Consider the following shell script:
#! /bin/bash | |
if [ ! -n "$PREFIX" ]; then | |
echo "$0: no PREFIX defined!" 1>&2 | |
exit | |
fi | |
#if [ ! -d dist ]; then | |
# echo "$0: no dist directory. Have you built?" 1>&2 | |
# exit | |
#fi | |
mylib_o=`find . -name mylib.o` | |
if [ ! -n "$mylib_o" ]; then | |
echo "$0: can't find mylib.o!" 1>&2 | |
exit | |
fi | |
ghci -package hxt-7.4 Main.hs \ | |
-L$PREFIX/lib -lhdf5 -lexpat -lfftw3f -lmylib \ | |
$mylib_o |
We might look for a directory named dist if building with Cabal.
The FFI gateway between my Haskell code and my C library is in a file named mylib.hs and compiles to mylib.o, whose path ghci needs to know in order to load all dependencies.
Finally, we invoke ghci. This particular program used hxt, the Haskell XML Toolbox, and mylib links against HDF5, the expat XML parser, and the single-precision FFTW.
For projects built with Cabal, the build system already knows all this information. With cabal-install, it's already possible to configure, build, test, and install Haskell packages. It'd be sweet to be able to easily load complex packages in ghci instead of having to resort to such hackery!
No comments:
Post a Comment