From HaskellWiki
Jump to navigation Jump to search


Salsa is an experimental Haskell library and code generator that allows Haskell programs to host the .NET runtime and interact with .NET libraries. It uses type families extensively to provide a type-safe mapping of the .NET object model in the Haskell type system.


GHC 7.8
Salsa makes extensive use of type families and thus requires at least version 7.8 of GHC.
Microsoft .NET Framework 3.5
Since the Salsa code generator requires .NET 3.5, any Salsa development also requires this version. Executables produced with Salsa however will run with just .NET 2.0 (provided that only .NET 2.0 assemblies are used by the program).
Mono support has been implemented. Salsa will be compiled against Mono if not running on windows or the flag 'use_mono' is set.
Salsa will not work with versions 1.0/1.1 of the .NET Framework.
Salsa is experimental and has not been thoroughly tested. A single typographical error can trigger multiple pages of errors from GHC, or cause it to eat lots of memory.

Getting Salsa

You can find Salsa on Hackage, but it is not getting updated frequently due to the manual build steps required. Please instead go directly to the repository on GitHub:

git clone

Using Salsa

Having a look at the sample programs in the Salsa distribution is probably the best way to learn how to use Salsa at the moment. There are currently three sample programs available:

  • Hello: a basic console 'Hello World' program.
  • Weather: a console program that asynchronously downloads the Sydney weather forecast and displays it.
  • Conway: a simulator for Conway's Game of Life with a Windows Presentation Foundation GUI. (Requires .NET 3.0 or later.)

C# in Haskell

The following table shows some C# code snippets and what they translate to:

C# Salsa Notes
<pre-c>o.ToString()</pre-c> o # _toString () Method names have a leading underscore and lowercase first character.
<pre-c>Console.Write("Hi {0}!", "world");</pre-c> _Console # _write ("Hi {0}!", "world") Static methods are called similarly.
<pre-c>Button b = new Button();</pre-c> b <- new _Button () Constructor names have a leading underscore.
<pre-c>s.Length</pre-c> get s _Length Use the get function to retrieve field and property values. The field/property has a leading underscore.
<pre-c>b.Text = "OK";</pre-c> set b [_Text := "OK"] Use the set function to set the value of fields and properties. Multiple assignments can be made in the one call.
<pre-c>b.Width = 10;</pre-c> set b [_Width :== 10 ] Use :== to assign without applying implicit conversions. This is useful for assigning polymorphic numeric literals to properties, since polymorphic-typed values confuse the Salsa coercion machinery.
<pre-c>b.Click += (EventHandler)
 delegate(...) { ... };</pre-c>
set b [_Click :+> delegate _EventHandler (...)] Use :+> to add a handler to an event, and delegate to wrap a Haskell function as a .NET delegate.


There are a number of .NET features that Salsa does not currently support. These include:

  • generic methods and classes
  • multi-dimensional arrays
  • explicit coercions
  • indexer properties
  • exception handling

Also, only a handful of value types are automatically marshaled between Haskell and .NET (these are Int32, String, Bool and Double). All other types are marshaled by reference (which is typically what you want for .NET reference types anyway).

(Patches are certainly welcome.)


Some of the inner workings of Salsa are described in my undergraduate thesis. In particular, Chapter 8 describes how type families are used to provide a type-safe mapping of the .NET object model in Haskell. If you're considering playing with Salsa, it is probably worth a read:

A .NET Bridge for Haskell: Dancing with the Devil