https://wiki.haskell.org/api.php?action=feedcontributions&user=RichN&feedformat=atomHaskellWiki - User contributions [en]2024-03-29T08:41:51ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Web/Literature/Practical_web_programming_in_Haskell&diff=15258Web/Literature/Practical web programming in Haskell2007-08-25T04:04:09Z<p>RichN: Flesh out the section about CGIT.</p>
<hr />
<div>[[Category:Tutorials]]<br />
{{Template:Formal under construction}}<br />
<br />
== Introduction ==<br />
<br />
This tutorial aims to get you started with writing web applications<br />
in Haskell. We describe a relatively light-weight <br />
approach to Haskell web programming<br />
which uses a CGI library and an XHTML combinator library. <br />
<br />
We think that while the approach we describe here is not as sophisticated<br />
or innovative as some other approaches, it is simple, portable and easy<br />
to understand if you are already familiar with web programming in other <br />
languages.<br />
<br />
The tutorial starts with preliminaries such as how to install the<br />
necessary software and how to compile and run your web<br />
applications. We then show a number of working small example programs<br />
which introduce the basic features of the CGI and XHtml libraries. We<br />
then move on to how to use monad transformers to add application<br />
specific functionality such as sessions to the CGI monad, and how to<br />
create database-driven web applications.<br />
We also present FastCGI, and an approach to using dynamically<br />
loaded Haskell code.<br />
<br />
=== Other approaches ===<br />
<br />
[Web Authoring System Haskell <br />
(WASH) [http://www.informatik.uni-freiburg.de/~thiemann/WASH/].<br />
Domain-specific embedded language. Type-safe forms handling. <br />
Threads continuation through client. This gives good<br />
back-button and session splitting properties.<br />
<br />
Haskell Application Server <br />
(HAppS) [http://happs.org/].<br />
Complete system including web server in one program.<br />
Uses XSLT for output.<br />
<br />
Haskell Server Pages <br />
(HSP) [http://www.cs.chalmers.se/~d00nibro/hsp/].<br />
Uses preprocessor to make XML tags into Haskell expressions.<br />
Dynamic compilation.<br />
<br />
<br />
=== Assumed knowledge ===<br />
<br />
This tutorial is not meant as an introduction to Haskell or web programming.<br />
We will assume that you have some familiarity with the following <br />
concepts:<br />
<br />
==== Haskell ====<br />
<br />
This tutorial is not meant as a first introduction to Haskell. If you<br />
want to learn about Haskell in general, have a look at the list of [[books and tutorials]]. You may want to start with [[Haskell in 5 steps]].<br />
<br />
==== (X)HTML ====<br />
<br />
[http://www.w3.org/MarkUp/ HTML (HyperText Markup Language)] is the <br />
"the lingua franca for publishing hypertext on the World Wide Web''.<br />
The XHtml library which we use in this tutorial produces <br />
[http://www.w3.org/TR/xhtml1/ XHTML 1.0], which is <br />
[http://www.w3.org/TR/html401/ HTML 4.0] formulated as <br />
[http://www.w3.org/XML/ XML].<br />
<br />
The combinators in the XHtml library do not make much sense unless you<br />
understand at least some parts of HTML. <br />
<br />
==== CGI ====<br />
<br />
CGI (Common Gateway Interface) programs are programs which run on the<br />
web server. They are given input which comes from the user's browser, <br />
and their output is given to the browser.<br />
<br />
To really understand how the CGI library works, you probably need to know<br />
a thing or two about CGI. The authoritative resource on CGI is the<br />
[http://hoohoo.ncsa.uiuc.edu/cgi/interface.html CGI specification].<br />
<br />
<br />
== Required software ==<br />
<br />
=== Haskell compiler ===<br />
<br />
[[GHC]], the Glasgow Haskell <br />
Compiler, is the Haskell implementation that we will use in this tutorial. <br />
However, any Haskell implementation that supports Haskell98 and multi-parameter<br />
type classes should work.<br />
<br />
=== Libraries: xhtml and cgi ===<br />
<br />
If your Haskell implementation does not come with the <tt>xhtml</tt> and<br />
<tt>cgi</tt> packages, download them from <br />
[http://hackage.haskell.org/ HackageDB].<br />
<br />
=== Web server ===<br />
<br />
You need to have access to a web server on which you can run CGI programs.<br />
The most convenient way to do this when learning and developing is to run<br />
a web server on your development machine. If you run the programs on some<br />
other machine you need to make sure that you compile your programs <br />
so that they can run on that machine. This normally means that the machines<br />
must to have the same architecture and run the same operating system. <br />
Linking your applications statically <br />
by giving the flags <tt>-static -optl-static</tt> to GHC <br />
will avoid problems with missing libraries on the web server.<br />
<br />
You could also use the [[Haskell Web Server]].<br />
<br />
<br />
== Compiling and running web applications ==<br />
<br />
Use GHC to produce a binary executable called <tt>prog.cgi</tt> from the Haskell <br />
source code file <tt>prog.hs</tt>:<br />
<pre><br />
ghc --make -package cgi -package xhtml -o prog.cgi prog.hs<br />
</pre><br />
<br />
Put the compiled program in the cgi-bin directory,<br />
or give it the extension .cgi, depending on the configuration<br />
of the web server.<br />
<br />
Linking your applications statically <br />
by giving the flags <tt>-static -optl-static</tt> to GHC <br />
will avoid problems with missing libraries on the web server.<br />
<br />
To run the compiled program, visit the URL of the CGI <br />
program with your web browser.<br />
<br />
<br />
== Simple examples ==<br />
<br />
=== Hello World ===<br />
<br />
Here is a very simple example which just outputs some static HTML.<br />
The type signatures in this code are optional. We show them here <br />
for clarity, but omit them in some later examples.<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
page :: Html <br />
page = body << h1 << "Hello World!"<br />
<br />
cgiMain :: CGI CGIResult<br />
cgiMain = output $ renderHtml page<br />
<br />
main :: IO ()<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
The <code>page</code> function constructs an HTML document which consists<br />
of a body containing a single header element which contains the text<br />
"Hello World". The CGI-action <code>cgiMain</code> renders the HTML document<br />
as a string, and produces that string as output. The <code>main</code> function<br />
runs <code>cgiMain</code>, using the normal CGI protocol for input and output.<br />
It also uses <code>handleErrors</code> to output an error page in case |cgiMain|<br />
throws an exception.<br />
<br />
Fans of one-liners may like this version better (<code>handleErrors</code> has been <br />
omitted since this simple program will not throw any exceptions):<br />
<br />
<haskell><br />
import Text.XHtml<br />
import Network.CGI<br />
<br />
main = runCGI $ output $ renderHtml $ body << h1 << "Hello World!"<br />
</haskell><br />
<br />
These are some of the important functions used in this example:<br />
<br />
<haskell><br />
-- creates a string containing the HTML document.<br />
renderHtml :: Html -> String<br />
<br />
-- outputs a string as the body of the HTTP response.<br />
output :: String -> CGI CGIResult<br />
<br />
-- Catches any exception thrown by the given CGI action, returns an <br />
-- error page with a 500 Internal Server Error, showing the exception <br />
-- information, and logs the error.<br />
handleErrors :: CGI CGIResult -> CGI CGIResult<br />
<br />
-- Runs a CGI action which produces a CGIResult, using the CGI protocol<br />
-- to get the inputs and send the outputs.<br />
runCGI :: CGI CGIResult -> IO ()<br />
</haskell><br />
<br />
==== HTML combinators ====<br />
<br />
See also [http://www.cse.ogi.edu/~andy/html/intro.htm].<br />
<br />
<code>Html</code> is the type of HTML fragments. It comes from the <code>Text.XHtml</code> module.<br />
There are functions for all XHTML 1.0 elements. <br />
Some examples:<br />
<br />
* header, body<br />
* h1, h2, ...<br />
* thediv<br />
* p<br />
* image<br />
<br />
The <code><<</code> operator is used for nesting HTML.<br />
<br />
Attributes are added to tags using the <code>!</code> operator.<br />
<br />
The function <code>renderHtml</code> (FIXME: explain variants) produces a string containing the<br />
document.<br />
<br />
<br />
=== Getting user input ===<br />
<br />
This program shows a form which asks the user for her name.<br />
When the form is submitted, the program greets the user by name.<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
inputForm = form << [paragraph << ("My name is " +++ textfield "name"),<br />
submit "" "Submit"]<br />
<br />
greet n = paragraph << ("Hello " ++ n ++ "!")<br />
<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
cgiMain = do mn <- getInput "name"<br />
let x = maybe inputForm greet mn<br />
output $ renderHtml $ page "Input example" x<br />
<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
<haskell><br />
-- Get the value of an input variable, for example from a form. <br />
-- If the variable has multiple values, the first one is returned.<br />
getInput :: String -> CGI (Maybe String)<br />
</haskell><br />
<br />
=== Cookies ===<br />
<br />
<haskell><br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
import Control.Monad (liftM)<br />
import Data.Maybe (fromMaybe)<br />
<br />
hello :: Int -> Html<br />
hello 0 = h1 << "Welcome!"<br />
+++ p << "This is the first time I see you."<br />
hello c = h1 << "Welcome back!"<br />
+++ p << ("I have seen you " ++ show c ++ " times before.")<br />
<br />
page :: String -> Html -> Html<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
cgiMain :: CGI CGIResult<br />
cgiMain = do c <- liftM (fromMaybe 0) $ readCookie "mycookie"<br />
setCookie (newCookie "mycookie" (show (c+1)))<br />
output $ renderHtml $ page "Cookie example" $ hello c<br />
<br />
main :: IO ()<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
Here we use <code>newCookie</code>, <code>setCookie</code> and <code>readCookie</code> to store and retrieve a counter<br />
cookie in the browser. If you want to get the string value of a cookie, use <code>getCookie</code> instead of <code>readCookie</code>.<br />
<br />
<br />
=== File uploads ===<br />
<br />
FIXME: use a safer example<br />
<br />
<haskell><br />
-- Accepts file uploads and saves the files in the given directory.<br />
-- WARNING: this script is a SECURITY RISK and only for <br />
-- demo purposes. Do not put it on a public web server.<br />
<br />
import Network.CGI<br />
import Text.XHtml<br />
<br />
import qualified Data.ByteString.Lazy as BS<br />
<br />
import Control.Monad (liftM)<br />
import Data.Maybe (fromJust)<br />
<br />
uploadDir = "../upload"<br />
<br />
fileForm = form ! [method "post", enctype "multipart/form-data"]<br />
<< [afile "file", submit "" "Upload"]<br />
saveFile n =<br />
do cont <- liftM fromJust $ getInputFPS "file"<br />
let f = uploadDir ++ "/" ++ basename n<br />
liftIO $ BS.writeFile f cont<br />
return $ paragraph << ("Saved as " +++ anchor ! [href f] << f +++ ".")<br />
<br />
page t b = header << thetitle << t +++ body << b<br />
<br />
basename = reverse . takeWhile (`notElem` "/\\") . reverse<br />
<br />
cgiMain = <br />
do mn <- getInputFilename "file"<br />
h <- maybe (return fileForm) saveFile mn<br />
output $ renderHtml $ page "Upload example" h<br />
<br />
main = runCGI $ handleErrors cgiMain<br />
</haskell><br />
<br />
We first output a file upload form, which should use the HTTP POST method, <br />
and the multipart/form-data content type. Here we seen an example of the use of<br />
HTML attributes, added with the <code>!</code> operator.<br />
<br />
For efficiency reasons, we use Data.ByteString.Lazy to represent the file contents.<br />
getInputFPS gets the value of an input variable as a lazy ByteString.<br />
<br />
<br />
=== Error handling ===<br />
<br />
handleErrors catches all exceptions and <br />
outputs a default error page with some information about the exception.<br />
You can write you own exception handler if you want to do something else<br />
when an exception is thrown. It can be useful to set<br />
the response code, e.g. 404.<br />
<br />
=== Returning non-HTML ===<br />
<br />
Of course we do not have to output HTML. Use setHeader to set the value<br />
of the Content-type header, and you can output whatever string you like. <br />
<br />
Examples: RSS<br />
<br />
=== Setting response headers ===<br />
<br />
You can use the <code>setHeader</code> function to set arbitrary HTTP response headers.<br />
You can also set the response code, as seen above.<br />
<br />
Example: output raw file data (with last-modified)<br />
<br />
<br />
<br />
== Going further ==<br />
<br />
This section explores some of possibilities beyond the basic web application<br />
programming.<br />
<br />
=== Extending the CGI monad with monad transformers ===<br />
<br />
At this point, you should be able to create many useful CGI scripts.<br />
As your scripts get more ambitious, however, you may find yourself<br />
needing to pass "global" parameters to your CGI actions (e.g. database<br />
connections, session information.) Rather than explicitly passing<br />
these values around, you can extend the CGI monad to do this work for<br />
you.<br />
<br />
The <hask>Network.CGI.Monad</hask> module defines a CGI monad<br />
transformer, allowing us to build a new monad that does everything the<br />
CGI monad does -- and more!<br />
<br />
For example, let's define a new CGI monad that provides a database<br />
connection (in this example, we use the<br />
<hask>Database.HSQL.PostgreSQL</hask> module for our database.) Since<br />
it will be used by the CGI application, I'll call the new monad "App".<br />
<br />
After importing the appropriate modules, we define a new type,<br />
<hask>AppT</hask> that is made up two monad transformers,<br />
<hask>CGIT</hask> and <hask>ReaderT</hask>. The <hask>CGIT</hask><br />
monad "wraps" the base monad "m". The <hask>CGIT</hask> monad, in<br />
turn, is wrapped by the <hask>ReaderT</hask> monad, which contains, in<br />
its environment, the database <hask>Connection</hask>.<br />
<br />
<hask>AppT</hask> takes two type parameters. The first is the base<br />
monad that the monad transformers are modifying. Usually this will be<br />
the <hask>IO</hask> monad. The second type is the data type that an<br />
action in the monad will return.<br />
<br />
<haskell><br />
import Control.Monad.Reader<br />
import Network.CGI<br />
import Network.CGI.Monad<br />
import Database.HSQL.PostgreSQL<br />
<br />
newtype AppT m a = App (ReaderT Connection (CGIT m) a)<br />
deriving (Monad, MonadIO, MonadReader Connection)<br />
</haskell><br />
<br />
Like <hask>CGI</hask>, we make a type synonym that defines the most<br />
common use of this new monad.<br />
<br />
<haskell><br />
type App a = AppT IO a<br />
</haskell><br />
<br />
We're not quite finished defining <hask>App</hask> yet. In order to be<br />
used like the CGI monad, <hask>App</hask> needs to be an instance of<br />
the <hask>MonadCGI</hask> class. This class defines two functions that<br />
we must support.<br />
<br />
<haskell><br />
instance MonadCGI (AppT IO) where<br />
cgiAddHeader n v = App $ lift $ cgiAddHeader n v<br />
cgiGet x = App $ lift $ cgiGet x<br />
</haskell><br />
<br />
So now we have an App monad that gives us all the functionality of<br />
CGI, but also carries around a database connection. The last step is<br />
to define the function that creates the monad so we can run actions<br />
inside it.<br />
<br />
<haskell><br />
import Control.Exception (bracket)<br />
import System.IO (stdin, stdout)<br />
<br />
runApp :: App CGIResult -> IO ()<br />
runApp (App a) =<br />
bracket (connect "host" "db" "user" "password")<br />
disconnect<br />
(\c -> do { env <- getCGIVars<br />
; hRunCGI env stdin stdout (runCGIT (runReaderT a c))<br />
; return () } )<br />
</haskell><br />
<br />
(either fill in your account/password information, or change<br />
<hask>runApp</hask> to accept the paramters as function arguments.)<br />
The function uses <hask>bracket</hask> so that the database connection<br />
gets released properly when the monad ends or if an exception is<br />
thrown.<br />
<br />
=== FastCGI ===<br />
<br />
[http://www.fastcgi.com/ FastCGI] is a standard for CGI-like programs that are not restarted<br />
for every request. This reduces the overhead involved in handling each <br />
request, and reduces the servers response time for each request.<br />
The overhead involved in starting a new process for each<br />
request can also include the need to set up new DB connections <br />
every time. With FastCGI, DB connections can be reused.<br />
<br />
Install FastCGI. Get a web server which can run FastCGI programs.<br />
Import Network.FastCGI. Use runFastCGI.<br />
<br />
=== URL rewriting ===<br />
<br />
=== Dynamic loading ===<br />
<br />
== Database-driven web-applications ==<br />
<br />
==== Persistent DB connections with FastCGI ====<br />
<br />
=== Web services ===<br />
<br />
== Existing applications ==<br />
<br />
[http://hackage.haskell.org/ HackageDB web interface].<br />
<br />
[http://www.bringert.net/ Hope].<br />
<br />
<br />
''Authors: Björn Bringert''</div>RichNhttps://wiki.haskell.org/index.php?title=GHC/FAQ&diff=2251GHC/FAQ2006-02-09T16:47:21Z<p>RichN: The last question in the Input/Output section wasn't marked up correctly.</p>
<hr />
<div>= The GHC FAQ =<br />
<br />
Please feel free to add stuff here.<br />
<br />
This page is rather long. We've started to add some sub-headings, but would welcome your help in making it better organsised.<br />
<br />
---------------------------------------<br />
= GHC on particular platforms =<br />
<br />
== How do I port GHC to platform X? ==<br />
<br />
There are two distinct possibilities: either<br />
<br />
* The hardware architecture for your system is already supported by GHC, but you're running an OS that isn't supported (or perhaps has been supported in the past, but currently isn't). This is the easiest type of porting job, but it still requires some careful bootstrapping.<br />
<br />
* Your system's hardware architecture isn't supported by GHC. This will be a more difficult port (though by comparison perhaps not as difficult as porting gcc).<br />
<br />
Both ways require you to bootstrap from intermediate HC files: these are the stylised C files generated by GHC when it compiles Haskell source. Basically the idea is to take the HC files for GHC itself to the target machine and compile them with gcc to get a working GHC, and go from there.<br />
<br />
The [http://www.haskell.org/ghc/docs/latest/html/building Building Guide] has all the details on how to bootstrap GHC on a new platform.<br />
<br />
<br />
== GHC on Linux ==<br />
<br />
=== I Can't run GHCi on Linux, because it complains about a missing <tt>libreadline.so.3</tt>. ===<br />
<br />
The "correct" fix for this problem is to install the correct RPM for the particular flavour of Linux on your machine. If this isn't an option, however, there is a hack that might work: make a symbolic link from <tt>libreadline.so.4</tt> to <tt>libreadline.so.3</tt> in <tt>/usr/lib</tt>. We tried this on a SuSE 7.1 box and it seemed to work, but YMMV.<br />
<br />
== Linking a program causes the following error on Linux: <tt>/usr/bin/ld: cannot open -lgmp: No such file or directory</tt> ==<br />
<br />
The problem is that your system doesn't have the GMP library installed. If this is a RedHat distribution, install the RedHat-supplied gmp-devel package, and the gmp package if you don't already have it. There have been reports that installing the RedHat packages also works for SuSE (SuSE doesn't supply a shared gmp library).<br />
<br />
== GHC on Solaris ==<br />
=== Solaris users may sometimes get link errors due to libraries needed by GNU Readline. ===<br />
<br />
We suggest you try linking in some combination of the termcap, curses and ncurses libraries, by giving <tt>-ltermcap</tt>, <tt>-lcurses</tt> and <tt>-lncurses</tt> respectively. If you encounter this problem, we would appreciate feedback on it, since we don't fully understand what's going on here.<br />
The build fails in readline.<br />
<br />
It has been reported that if you have multiple versions of the readline library installed on Linux, then this may cause the build to fail. If you have multiple versions of readline, try uninstalling all except the most recent version.<br />
<br />
== GHC on Windows ==<br />
=== My program that uses a really large heap crashes on Windows. ===<br />
<br />
For utterly horrible reasons, programs that use more than 128Mb of heap won't work when compiled dynamically on Windows (they should be fine statically compiled).<br />
<br />
=== I can't use readline under GHCi on Windows ===<br />
<br />
In order to load the readline package under GHCi on Windows, you need to make a version of the readline library that GHCi can load. Instructions for GHC 6.2.2. are here.<br />
<br />
=== Ctrl-C doesn't work on Windows ===<br />
<br />
When running GHC under a Cygwin shell on Windows, Ctrl-C sometimes doesn't work. The workaround is to use Ctrl-Break instead.<br />
<br />
=== How do I link Haskell with C++ code compiled by Visual Studio? ===<br />
<br />
==== Prerequisites ====<br />
<br />
It is assumed that the reader is familiar with the Haskell <br />
[http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi.html Foreign function interface (FFI)],<br />
and is able to compile Haskell programs with GHC and C++ programs with Visual Studio.<br />
<br />
==== Background ====<br />
<br />
GHC has two modes of code generation. It either compiles Haskell straight into object code<br />
(native mode), or translates Haskell into intermediate C code, and uses a C compiler as backend.<br />
<br />
The Windows distribution of GHC comes bundled with the GCC compiler, which is used as backend.<br />
That's why linking Haskell with Visual C++ is no different from linking GCC-generated code with<br />
the code generated by Visual C++.<br />
<br />
One cannot statically link together object files produced by those two compilers,<br />
but they can be linked dynamically: an executable produced by Visual C++ can invoke a DLL<br />
produced by GCC, and vice versa. Likewise, we can link Haskell with Visual C++ in one of these ways.<br />
<br />
''Note:'' if Haskell ever becomes able to use Visual C++ as a backend, we would simply list<br />
all source files (Haskell and C++) on the command line of GHC.<br />
<br />
==== Invoking a Haskell DLL from a C++ executable ====<br />
<br />
#Make a Haskell DLL as explained in [http://www.haskell.org/ghc/docs/latest/html/users_guide/win32-dlls.html#win32-dlls-foreign]<br />
#Make a module definition file, such as<tt><br>LIBRARY Adder<br>EXPORTS<br>&nbsp;&nbsp;&nbsp;&nbsp;adder</tt><br />
#Create an import library using Visual Studio's <tt>lib.exe:<br>lib /DEF:adder.def</tt><br />
#Link the C++ program against the import library.<br />
<br />
==== Invoking a C++ DLL from a Haskell executable ====<br />
<br />
#Make a DLL project in Visual Studio. It will create a <tt>.vcproj</tt> and <tt>.sln</tt> files for you. Add your C++ source files to this project. <br />
#Create a <tt>.def</tt> file for your DLL. It might look like<tt><br>LIBRARY MyDLL<br>EXPORTS<br>&nbsp;&nbsp;&nbsp;&nbsp;function1<br>&nbsp;&nbsp;&nbsp;&nbsp;function2<br></tt> where <tt>function1</tt> and <tt>function2</tt> are the names of the C++ functions that you want to invoke from Haskell (there can be more of them, of course), <tt>MyDLL</tt> is the name of your DLL.<br />
#Create an import library that can be used by <tt>ghc:<br>dlltool -d MyDLL.def -l libMyDLL.a</tt> <br />
#Link your Haskell project, adding the library:<tt><br>ghc --make main.hs -optl-lMyDLL -optl-L.<br></tt>''mind the dot at the end of the command line!''<br> (<tt>[http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#forcing-options-through -optl]</tt> switch passes its argument as an option to the linker).<br />
<br />
== Why isn't GHC available for .NET? ==<br />
<br />
<br />
It wouldd make a lot of sense to give GHC a .NET back end, and it's a<br />
question that comes up regularly. The reason that we haven't done it<br />
here, at GHC HQ, is because it's a more substantial undertaking than<br />
might at first appear (see below). Furthermore, it'd permanently add a<br />
complete new back-end platform for us to maintain. Given our rather<br />
limited development effort, we have so far not bitten<br />
the bullet, and we have no immediate plans to do so.<br />
<br />
It would be a good, well-defined project for someone else to tackle, and<br />
we would love to see it done. There is some good groundwork already done:<br />
<br />
* Sigbjorn Finne did a simple interop implementation that allows a Haskell program to be compiled to native code (as now) but to call .NET programs via a variant of the FFI. I don't think this work is in active use, and I'd be surprised if it worked out of the box, but it could probably be revived with modest effort<br />
<br />
* Andre Santos and his colleagues at UFPE in Brazil are working on a .NET back end, that generates CLR IL, though I don't know where they are up to.<br />
<br />
* Nigel Perry and Oliver Hunt have a Haskell.NET prototype that works using GHC to compile to Core, and then compiling Core to NET. I'm not sure what stage it is at.<br />
<br />
* GHC.Net would be extra attractive if there was a Visual Studio integration for GHC. Substantial progress on this has been made in 2004 by Simon Marlow, Krasimir Angelov, and Andre Santos and colleagues.<br />
<br />
There may be others that I don't know of. If anyone wants to join in<br />
this effort, do contact the above folk. And please keep us informed!<br />
<br />
Here's a summary of why it's a non-trivial thing to do:<br />
<br />
* The first thing is to generate native CLR Intermediate Language (IL). That's not really hard. Requires thinking about representations for thunks and functions, and it may not be particularly efficient, but it can surely be done. An open question is about whether to generate verifiable IL or not. The trouble here is that Haskell's type system is more expressive than the CLR's in some ways, notably the use of higher-kinded type variables. So, to generate verifiable IL one is bound to need some run-time casts, and it's not clear how to minimise these.<br />
<br />
At first blush this is *all* you need do. But it isn't!<br />
<br />
* Next, you need to think about how to inter-operate with .NET libraries. You don't really want to write "foreign import..." for each and every import. You'd like GHC to read the CLR meta-data directly. But there are lots of tricky issues here; see the paper that Mark Shields and I wrote about "Object-oriented style overloading for Haskell".<br />
<br />
* Now you need to figure out how to implement GHC's primitive operations:<br />
* the I/O monad<br />
* arbitrary precision arithmetic<br />
* concurrency<br />
* exceptions<br />
* finalisers<br />
* stable pointers<br />
* software transactional memory Not all of these are necessary, of course, but many are used in the libraries. The CLR supports many of them (e.g. concurrency) but with a very different cost model.<br />
<br />
* Last, you have to figure out what to do for the libraries. GHC has a pretty large library, and you either have to implement the primops on which the library is based (see previous point), or re-implement it. For example, GHC's implementation of I/O uses mutable state, concurrency, and more besides. For each module, you need to decide either to re-implement it using .NET primitives, or to implement the stuff the module is based on.<br />
<br />
These challenges are mostly broad rather than deep. But to get a<br />
production quality implementation that runs a substantial majority of<br />
Haskell programs "out of the box" requires a decent stab at all of them.<br />
<br />
---------------------------------------<br />
= Running GHC =<br />
<br />
== GHC doesn't like filenames containing +. ==<br />
<br />
Indeed not. You could change <tt>+</tt> to <tt>p</tt> or <tt>plus</tt>.<br />
<br />
== Why does linking take so long? ==<br />
<br />
Linking a small program should take no more than a few seconds. Larger programs can take longer, but even linking GHC itself only takes 3-4 seconds on our development machines.<br />
<br />
Long link times have been attributed to using Sun's linker on Solaris, as compared to GNU ld which appears to be much faster. So if you're on a Sun box, try switching to GNU ld. [http://www.haskell.org/pipermail/glasgow-haskell-users/2002-November/004477.html This article] from the mailing list has more information.<br />
<br />
== Why do I get errors about missing include files when compiling with -O or -prof? ==<br />
<br />
Certain options, such as -O, turn on via-C compilation, instead of using the native code generator. Include files named by -#include options or in foreign import declarations are only used in via-C compilation mode. See [http://www.haskell.org/ghc/docs/latest/html/users_guide/sec-ffi-ghc.html#finding-header-files Section 8.2.2.1, ´Finding Header files¡] for more details.<br />
<br />
== How do I compile my program for profiling without overwriting the object files and hi files I've already built? ==<br />
<br />
You can select alternative suffixes for object files and interface files, so you can have several builds of the same code coexisting in the same directory. For example, to compile with profiling, you might do this:<br />
<br />
<pre><br />
ghc --make -prof -o foo-prof -osuf p.o -hisuf p.hi Main<br />
</pre><br />
<br />
See [http://www.haskell.org/ghc/docs/latest/html/users_guide/separate-compilation.html#options-output Section 4.6.4, ´Redirecting the compilation output(s)¡] for more details on the <tt>-osuf</tt> and <tt>-hisuf</tt> options.<br />
<br />
---------------------------------------<br />
= Syntax =<br />
<br />
== I can't get string gaps to work ==<br />
<br />
If you're also using CPP, beware of the known pitfall with string gaps mentioned in [http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#cpp-string-gaps Section 4.10.3.1, �%G��%@-Y´CPP and string gaps¡].<br />
<br />
---------------------------------------<br />
= GHCi =<br />
<br />
== GHCi complains about missing symbols like CC_LIST when loading a previously compiled .o file. ==<br />
<br />
This probably means the .o files in question were compiled for profiling (with -prof). Workaround: recompile them without profiling. We really ought to detect this situation and give a proper error message.<br />
<br />
== When I try to start ghci (probably one I compiled myself) it says <tt>ghc-5.02: not built for interactive use</tt> ==<br />
<br />
To build a working ghci, you need to build GHC 5.02 with itself; the above message appears if you build it with 4.08.X, for example. It'll still work fine for batch-mode compilation, though. Note that you really must build with exactly the same version of the compiler. Building 5.02 with 5.00.2, for example, may or may not give a working interactive system; it probably won't, and certainly isn't supported. Note also that you can build 5.02 with any older compiler, back to 4.08.1, if you don't want a working interactive system; that's OK, and supported.<br />
<br />
== I get an error message from GHCi about a "<tt>duplicate definition for symbol __module_registered</tt>" ==<br />
<br />
An error message like this:<br />
<br />
<pre><br />
GHCi runtime linker: fatal error: I found a duplicate definition for symbol<br />
__module_registered<br />
whilst processing object file<br />
/usr/local/lib/ghc-6.2/HSfgl.o<br />
</pre><br />
<br />
probably indicates that when building a library for GHCi (<tt>HSfgl.o</tt> in the above example), you should use the <tt>-x</tt> option to <tt>ld</tt>.<br />
<br />
---------------------------------------<br />
= The Foreign Function Interface =<br />
<br />
== When do other Haskell threads get blocked by an FFI call? ==<br />
<br />
{| border="1" align="center"<br />
|<br />
! safe<br />
! unsafe<br />
|-<br />
! -threaded<br />
| NO <br />
| YES<br />
|-<br />
! no -threaded<br />
| YES<br />
| YES<br />
|}<br />
<br />
The <tt>-threaded</tt> flag (given when linking; see the <br />
[http://www.haskell.org/ghc/docs/latest/html/users_guide/flag-reference.html manual])<br />
allows other Haskell threads to run concurrently with a thread making an FFI call.<br />
This nice behaviour does not happen for foreign calls marked as `unsafe` (see<br />
the [http://www.cse.unsw.edu.au/~chak/haskell/ffi/ FFI Addendum]).<br />
<br />
There used to be another modifier, <tt>threadsafe</tt>, which is now deprecated. Use `safe` instead.<br />
<br />
== When I use a foreign function that takes or returns a float, it gives the wrong answer, or crashes. ==<br />
<br />
You should use the <tt>-#include</tt> option to bring the correct prototype into scope (see [http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#options-C-compiler Section 4.10.5, ´Options affecting the C compiler (if applicable)¡]).<br />
<br />
---------------------------------------<br />
= Input/Output =<br />
<br />
== If I print out a string using <tt>putStr</tt>, and then attempt to read some input using <tt>hGetLine</tt>, I don't see the output from the <tt>putStr</tt>. ==<br />
<br />
The <tt>stdout</tt> handle is line-buffered by default, which means that output sent to the handle is only flushed when a newline (/n) is output, the buffer is full, or <tt>hFlush</tt> is called on the <tt>Handle</tt>. The right way to make the text appear without sending a newline is to use <tt>hFlush</tt>:<br />
<br />
<pre><br />
import System.IO<br />
main = do<br />
putStr "how are you today? "<br />
hFlush stdout<br />
input &- hGetLine<br />
...<br />
</pre><br />
<br />
You'll probably find that the behaviour differs when using GHCi: the hFlush isn't necessary to make the text appear. This is because in GHCi we turn off the buffering on stdout, because this is normally what you want in an interpreter: output appears as it is generated.<br />
<br />
== If I explicitly set the buffering on a Handle to <tt>NoBuffering</tt> I'm not able to enter EOF by typing "Ctrl-D". ==<br />
<br />
This is a consequence of Unixy terminal semantics. Unix does line buffering on terminals in the kernel as part of the terminal processing, unless you turn it off. However, the Ctrl-D processing is also part of the terminal processing which gets turned off when the kernel line buffering is disabled. So GHC tries its best to get NoBuffering semantics by turning off the kernel line buffering, but as a result you lose Ctrl-D. C'est la vie.<br />
<br />
== When I open a FIFO (named pipe) and try to read from it, I get EOF immediately. ==<br />
<br />
This is a consequence of the fact that GHC opens the FIFO in non-blocking mode. The behaviour varies from OS to OS: on Linux and Solaris you can wait for a writer by doing an explicit threadWaitRead on the file descriptor (gotten from <tt>Posix.handleToFd</tt>) before the first read, but this doesn't work on FreeBSD (although rumour has it that recent versions of FreeBSD changed the behaviour to match other OSs). A workaround for all systems is to open the FIFO for writing yourself, before (or at the same time as) opening it for reading.<br />
<br />
== When I foreign import a function that returns char or short, I get garbage back. ==<br />
<br />
This is a known bug in GHC versions prior to 5.02.2. GHC doesn't mask out the more significant bits of the result. It doesn't manifest with gcc 2.95, but apparently shows up with g++ and gcc 3.0.<br />
<br />
= Optimization issues =<br />
<br />
== My program spent too much time doing garbage collection ==<br />
<br />
Add the "+RTS -A10m" option to the command line when you run your<br />
program. This sets the allocation area size used by the garbage<br />
collector to 10M, which should sufficiently decrease GC times (the<br />
default is 256K; see the section "Running a compiled program" in the<br />
users' guide). You can also add to your program C module containing<br />
statement<br />
<br />
char *ghc_rts_opts = "-A10m";<br />
<br />
to force your program to use this setting on each run.<br />
<br />
<br />
== Does GHC do common subexpression elimination? ==<br />
<br />
In general, GHC does not do CSE.<br />
It'd be a relatively easy pass for someone to add, but it can cause space leaks. And it can replace two strictly-evaluated calls with one lazy thunk:<br />
<pre><br />
let { x = case e of ....; y = case e of .... } in ...<br />
==><br />
let { v = e; x = case v of ...; y = case v of ... } in ...<br />
</pre><br />
Now <tt>v</tt> is allocated as a thunk. (Of course, that might be well worth it if <tt>e</tt> is an expensive expression.)<br />
<br />
Instead GHC does "opportunistic CSE". If you have <br />
<pre><br />
let x = e in .... let y = e in ....<br />
</pre><br />
then it'll discard the duplicate binding. This can still cause space<br />
leaks but it guarantees never to create a new thunk, and it turns out <br />
to be very useful in practice.<br />
<br />
Bottom line: if you care about sharing, do it yourself using <tt>let</tt> <br />
or <tt>where</tt>.<br />
<br />
---------------------------------------<br />
<br />
= Other frequently asked questions =<br />
<br />
== Do I have to recompile all my code if I upgrade GHC? ==<br />
<br />
Yes. There are two reasons for this:<br />
<br />
* GHC does a lot of cross-module optimisation, so compiled code will include parts of the libraries it was compiled against (including the Prelude), so will be deeply tied to the actual version of those libraries it was compiled against. When you upgrade GHC, the libraries may change; even if the external interface of the libraries doesn't change, sometimes internal details may change because GHC optimised the code in the library differently. <br />
* We sometimes change the ABI (application binary interface) between versions of GHC. Code compiled with one version of GHC is not necessarily compatible with code compiled by a different version, even if you arrange to keep the same libraries.<br />
<br />
== Why doesn't GHC use shared libraries? ==<br />
<br />
GHC does provide shared libraries, currently only on MacOS X. We are working on making shared libraries work on other platforms.<br />
<br />
However, GHC-compiled libraries are very tightly coupled, which means it's unlikely you'd be able to swap out a shared library for a newer version unless it was compiled with exactly the same compiler and set of libraries as the old version.<br />
<br />
== My program is failing with head [], or an array bounds error, or some other random error, and I have no idea how to find the bug. Can you help? ==<br />
<br />
Compile your program with <tt>-prof -auto-all</tt> (make sure you have the profiling libraries installed), and run it with <tt>+RTS -xc -RTS</tt> to get a ´stack trace¡ at the point at which the exception was raised. See [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-options-debugging Section 4.14.4, ´RTS options for hackers, debuggers, and over-interested souls¡] for more details.<br />
<br />
== How do I increase the heap size permanently for a given binary? ==<br />
<br />
See [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-hooks Section 4.14.5, ´´Hooks¡ to change RTS behaviour¡].<br />
<br />
== I'm trying to compile my program for parallel execution with the -parallel, and GHC complains with an error like ´failed to load interface file for Prelude¡. ==<br />
<br />
GHC doesn't ship with support for parallel execution; that support is provided separately by the [http://www.macs.hw.ac.uk/~dsg/gph/ GPH] project.<br />
<br />
== When is it safe to use <tt>unsafePerformIO</tt>? ==<br />
<br />
We'll give two answers to this question, each of which may be helpful. These criteria are not rigorous in any real sense (you'd need a formal semantics for Haskell in order to give a proper answer to this question), but should give you a feel for the kind of things you can and cannot do with unsafePerformIO.<br />
<br />
* It is safe to implement a function or API using unsafePerformIO if you could imagine also implementing the same function or API in Haskell without using unsafePerformIO (forget about efficiency, just consider the semantics).<br />
* In pure Haskell, the value of a function depends only on the values of its arguments (and free variables, if it has any). If you can implement the function using unsafePerformIO and still retain this invariant, then you're probably using unsafePerformIO in a safe way. Note that you need only consider the observable values of the arguments and result.<br />
<br />
For more information, see [http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003681.html this thread].<br />
<br />
== I can't get finalizers to work properly. My program sometimes just prints <tt><<loop>></tt>. ==<br />
<br />
Chances are that your program is trying to write a message to stdout or stderr in the finalizer. Handles have finalizers themselves, and since finalizers don't keep other finalized values alive, the stdout and stderr Handles may be finalized before your finalizer runs. If this happens, your finalizer will block on the handle, and probably end up receiving a NonTermination exception (which is printed as <tt><<loop>></tt>).<br />
<br />
== Does GHC implement any kind of extensible records? ==<br />
<br />
No, extensible records are not implemented in GHC. [http://www.haskell.org/hugs/ Hugs] implements TRex, one extensible record variant. The problem is that the record design space is large, and seems to lack local optima. And all reasonable variants break backward compatibility. As a result, nothing much happens.</div>RichN