hs-dotnet: Pragmatic .NET interop for Haskell

hs-dotnet is a pragmatic .NET interop layer for Haskell. It exposes both
.NET classes to Haskell (via GHC) and Haskell function values to .NET.
For mutual benefit, one would hope.

Download and Installation

The package is available either as a  Windows Installer (MSI) or as a source Cabal package:
The Windows Installer will give you the option of building the Cabal package from source or simply install it, but if you prefer to handle this yourself simply pick up the Cabal package directly and build+install it yourself.
The package has been tested with GHC-6.10.{1,2} on Windows with versions 2.0 and 3.5 of the .NET Framework.
NOTE: If you install via the MSIs and elect not to have the installer perform the 'install' step, you will have to do that yourself afterwards.
Simply go into the directory where you installed the package and type runghc Setup install to take care of this.


The examples/ directory in the package contains some Haskell samples of how to access
and use the package.  Here's how to program LINQ:
-- from examples/LinqQuery.hs
whereQuery :: IO ()
whereQuery = do
  intQ  <- newQueue (0::Int32)
  mapM_ (flip enqueue intQ) [1..5]

  let queryPred v = return (v>=3)
  putStrLn "Performing the query..."
   -- creating the LINQ query, passing it the (Haskell) predicate
  res <- intQ # whereQ queryPred
  putStrLn "..query done; predicate not yet invoked.."
   -- let's force the query by getting out a result list..
  ls    <- res # getList
  putStrLn ("Query result: " ++ show ls)
Here's another one,  computing the MD5 hash from a string:

module MD5 where

import NET
import Data.Word
import Numeric

calcMD5FromString :: String -> IO String
calcMD5FromString str = do
   md  <- invokeStatic "System.Security.Cryptography.MD5" "Create" ()
   fi  <- getFieldStatic "System.Text.Encoding" "ASCII" ()
   bs  <- fi  # invoke "GetBytes" str
   vec <- md  # invoke "ComputeHash" (bs :: Vector Word8)
   res <- vec # bytesToString
   let resStr = foldr (showHex) "" res
   return resStr

And getting file input via the File-Select Common Dialog:

module FileDialog where

import NET

selectFile :: IO String
selectFile = do
  obj <- new "System.Windows.Forms.FolderBrowserDialog"
  (obj :: Object ()) # invoke_ "ShowDialog" ()
  obj # getField "SelectedPath" ()

examples/Forms.hs shows how to build a .NET hosted UI application with a Concurrent
Haskell application running on the Haskell side, which the UI application calls back into.

More information on the API provided is included in the Haddock documentation.

To load up and test these examples, go into the examples/ directory and load them up
via ghci, e.g., ghci Forms.hs


A tool is provided for generating Haskell module wrappers for .NET classes; see the tools/
directory for the simple, easy-to-use tool hswrap. Documentation for it can be found in doc/


The interop layer is evolving; if you have feedback on what's there and what you wish
was available, please get in touch - sof at forkio.com

Sigbjorn Finne,
Apr 18, 2009, 3:32 PM
Sigbjorn Finne,
Apr 18, 2009, 1:24 PM