can get at the Raw Iron, if you are willing to write some non-standard
code at a more primitive level. You need not be “stuck” on
performance because of the implementation costs of Haskell's
-“high-level” features—you can always code “under” them. In an
-extreme case, you can write all your time-critical code in C, and then
-just glue it together with Haskell!
+“high-level” features—you can always code “under” them. In an extreme case, you can write all your time-critical code in C, and then just glue it together with Haskell!
</Para>
<Para>
</VarListEntry>
<VarListEntry>
-<Term>Calling out to C:</Term>
+<Term>Pattern guards</Term>
+<ListItem>
+<Para>
+Instead of being a boolean expression, a guard is a list of qualifiers, exactly as in a list comprehension. See <XRef LinkEnd="pattern-guards">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Foreign calling:</Term>
<ListItem>
<Para>
Just what it sounds like. We provide <Emphasis>lots</Emphasis> of rope that you
-can dangle around your neck. Please see <XRef LinkEnd="glasgow-ccalls">.
+can dangle around your neck. Please see <XRef LinkEnd="ffi">.
</Para>
</ListItem>
</VarListEntry>
Before you get too carried away working at the lowest level (e.g.,
sloshing <Literal>MutableByteArray#</Literal>s around your
program), you may wish to check if there are libraries that provide a
-“Haskellised veneer” over the features you want. See the
-accompanying library documentation.
+“Haskellised veneer” over the features you want. See
+<xref linkend="book-hslibs">.
</Para>
<Sect1 id="primitives">
</Para>
<Para>
-The <Literal>ST</Literal> library, which provides access to the <Function>ST</Function> monad, is a
-GHC/Hugs extension library and is described in the separate <ULink
-URL="libs.html"
->GHC/Hugs Extension Libraries</ULink
-> document.
+The <Literal>ST</Literal> library, which provides access to the
+<Function>ST</Function> monad, is described in <xref
+linkend="sec-ST">.
</Para>
</Sect1>
</Para>
<Para>
-Please see <XRef LinkEnd="glasgow-stablePtrs"> for more details.
+Please see <XRef LinkEnd="sec-stable-pointers"> for more details.
</Para>
</ListItem>
</VarListEntry>
</Para>
<Para>
-Please see <XRef LinkEnd="glasgow-foreignObjs"> for more details.
+Please see <XRef LinkEnd="sec-ForeignObj"> for more details.
</Para>
</ListItem>
</VarListEntry>
</Sect1>
-<Sect1 id="glasgow-ccalls">
-<Title>Calling C directly from Haskell
-</Title>
-<Para>
-<IndexTerm><Primary>C calls (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>_ccall_ (Glasgow extension)</Primary></IndexTerm>
-<IndexTerm><Primary>_casm_ (Glasgow extension)</Primary></IndexTerm>
-</Para>
+<Sect1 id="pattern-guards">
+<Title>Pattern guards</Title>
<Para>
-GOOD ADVICE: Because this stuff is not Entirely Stable as far as names
-and things go, you would be well-advised to keep your C-callery
-corraled in a few modules, rather than sprinkled all over your code.
-It will then be quite easy to update later on.
-</Para>
-
-<Sect2 id="ccall-intro">
-<Title><Function>_ccall_</Function> and <Function>_casm_</Function>: an introduction
-</Title>
-
-<Para>
-The simplest way to use a simple C function
+<IndexTerm><Primary>Pattern guards (Glasgow extension)</Primary></IndexTerm>
+The discussion that follows is an abbreviated version of Simon Peyton Jones's original <ULink URL="http://research.microsoft.com/~simonpj/Haskell/guards.html">proposal</ULink>. (Note that the proposal was written before pattern guards were implemented, so refers to them as unimplemented.)
</Para>
<Para>
+Suppose we have an abstract data type of finite maps, with a
+lookup operation:
<ProgramListing>
-double fooC( FILE *in, char c, int i, double d, unsigned int u )
+lookup :: FiniteMap -> Int -> Maybe Int
</ProgramListing>
+The lookup returns <Function>Nothing</Function> if the supplied key is not in the domain of the mapping, and <Function>(Just v)</Function> otherwise,
+where <VarName>v</VarName> is the value that the key maps to. Now consider the following definition:
</Para>
-<Para>
-is to provide a Haskell wrapper:
-</Para>
-
-<Para>
-
<ProgramListing>
-fooH :: Char -> Int -> Double -> Word -> IO Double
-fooH c i d w = _ccall_ fooC (“stdin”::Addr) c i d w
+clunky env var1 var2 | ok1 && ok2 = val1 + val2
+| otherwise = var1 + var2
+where
+ m1 = lookup env var1
+ m2 = lookup env var2
+ ok1 = maybeToBool m1
+ ok2 = maybeToBool m2
+ val1 = expectJust m1
+ val2 = expectJust m2
</ProgramListing>
-</Para>
-
<Para>
-The function <Function>fooH</Function> unbox all of its arguments, call the C
-function <Function>fooC</Function> and box the corresponding arguments.
+The auxiliary functions are
</Para>
-<Para>
-One of the annoyances about <Function>_ccall_</Function>s is when the C types don't quite
-match the Haskell compiler's ideas. For this, the <Function>_casm_</Function> variant
-may be just the ticket (NB: <Emphasis>no chance</Emphasis> of such code going
-through a native-code generator):
-</Para>
-
-<Para>
-
<ProgramListing>
-import Addr
-import CString
+maybeToBool :: Maybe a -> Bool
+maybeToBool (Just x) = True
+maybeToBool Nothing = False
-oldGetEnv name
- = _casm_ “%r = getenv((char *) %0);” name >>= \ litstring ->
- return (
- if (litstring == nullAddr) then
- Left ("Fail:oldGetEnv:"++name)
- else
- Right (unpackCString litstring)
- )
+expectJust :: Maybe a -> a
+expectJust (Just x) = x
+expectJust Nothing = error "Unexpected Nothing"
</ProgramListing>
-</Para>
-
<Para>
-The first literal-literal argument to a <Function>_casm_</Function> is like a <Function>printf</Function>
-format: <Literal>%r</Literal> is replaced with the “result,” <Literal>%0</Literal>–<Literal>%n-1</Literal> are
-replaced with the 1st–nth arguments. As you can see above, it is an
-easy way to do simple C casting. Everything said about <Function>_ccall_</Function> goes
-for <Function>_casm_</Function> as well.
+What is <Function>clunky</Function> doing? The guard <Literal>ok1 &&
+ok2</Literal> checks that both lookups succeed, using
+<Function>maybeToBool</Function> to convert the <Function>Maybe</Function>
+types to booleans. The (lazily evaluated) <Function>expectJust</Function>
+calls extract the values from the results of the lookups, and binds the
+returned values to <VarName>val1</VarName> and <VarName>val2</VarName>
+respectively. If either lookup fails, then clunky takes the
+<Literal>otherwise</Literal> case and returns the sum of its arguments.
</Para>
<Para>
-The use of <Function>_casm_</Function> in your code does pose a problem to the compiler
-when it comes to generating an interface file for a freshly compiled
-module. Included in an interface file is the unfolding (if any) of a
-declaration. However, if a declaration's unfolding happens to contain
-a <Function>_casm_</Function>, its unfolding will <Emphasis>not</Emphasis> be emitted into the interface
-file even if it qualifies by all the other criteria. The reason why
-the compiler prevents this from happening is that unfolding <Function>_casm_</Function>s
-into an interface file unduly constrains how code that import your
-module have to be compiled. If an imported declaration is unfolded and
-it contains a <Function>_casm_</Function>, you now have to be using a compiler backend
-capable of dealing with it (i.e., the C compiler backend). If you are
-using the C compiler backend, the unfolded <Function>_casm_</Function> may still cause you
-problems since the C code snippet it contains may mention CPP symbols
-that were in scope when compiling the original module are not when
-compiling the importing module.
+This is certainly legal Haskell, but it is a tremendously verbose and
+un-obvious way to achieve the desired effect. Arguably, a more direct way
+to write clunky would be to use case expressions:
</Para>
-<Para>
-If you're willing to put up with the drawbacks of doing cross-module
-inlining of C code (GHC - A Better C Compiler :-), the option
-<Option>-funfold-casms-in-hi-file</Option> will turn off the default behaviour.
-<IndexTerm><Primary>-funfold-casms-in-hi-file option</Primary></IndexTerm>
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-literal-literals">
-<Title>Literal-literals</Title>
+<ProgramListing>
+clunky env var1 var1 = case lookup env var1 of
+ Nothing -> fail
+ Just val1 -> case lookup env var2 of
+ Nothing -> fail
+ Just val2 -> val1 + val2
+where
+ fail = val1 + val2
+</ProgramListing>
<Para>
-<IndexTerm><Primary>Literal-literals</Primary></IndexTerm>
-The literal-literal argument to <Function>_casm_</Function> can be made use of separately
-from the <Function>_casm_</Function> construct itself. Indeed, we've already used it:
+This is a bit shorter, but hardly better. Of course, we can rewrite any set
+of pattern-matching, guarded equations as case expressions; that is
+precisely what the compiler does when compiling equations! The reason that
+Haskell provides guarded equations is because they allow us to write down
+the cases we want to consider, one at a time, independently of each other.
+This structure is hidden in the case version. Two of the right-hand sides
+are really the same (<Function>fail</Function>), and the whole expression
+tends to become more and more indented.
</Para>
<Para>
+Here is how I would write clunky:
+</Para>
<ProgramListing>
-fooH :: Char -> Int -> Double -> Word -> IO Double
-fooH c i d w = _ccall_ fooC (“stdin”::Addr) c i d w
+clunky env var1 var1
+ | Just val1 <- lookup env var1
+ , Just val2 <- lookup env var2
+ = val1 + val2
+...other equations for clunky...
</ProgramListing>
-</Para>
-
<Para>
-The first argument that's passed to <Function>fooC</Function> is given as a literal-literal,
-that is, a literal chunk of C code that will be inserted into the generated
-<Filename>.hc</Filename> code at the right place.
+The semantics should be clear enough. The qualifers are matched in order.
+For a <Literal><-</Literal> qualifier, which I call a pattern guard, the
+right hand side is evaluated and matched against the pattern on the left.
+If the match fails then the whole guard fails and the next equation is
+tried. If it succeeds, then the appropriate binding takes place, and the
+next qualifier is matched, in the augmented environment. Unlike list
+comprehensions, however, the type of the expression to the right of the
+<Literal><-</Literal> is the same as the type of the pattern to its
+left. The bindings introduced by pattern guards scope over all the
+remaining guard qualifiers, and over the right hand side of the equation.
</Para>
<Para>
-A literal-literal is restricted to having a type that's an instance of
-the <Literal>CCallable</Literal> class, see <XRef LinkEnd="ccall-gotchas">
-for more information.
+Just as with list comprehensions, boolean expressions can be freely mixed
+with among the pattern guards. For example:
</Para>
+<ProgramListing>
+f x | [y] <- x
+ , y > 3
+ , Just z <- h y
+ = ...
+</ProgramListing>
+
<Para>
-Notice that literal-literals are by their very nature unfriendly to
-native code generators, so exercise judgement about whether or not to
-make use of them in your code.
+Haskell's current guards therefore emerge as a special case, in which the
+qualifier list has just one element, a boolean expression.
</Para>
+</Sect1>
-</Sect2>
+ <sect1 id="sec-ffi">
+ <title>The foreign interface</title>
+
+ <para>The foreign interface consists of the following components:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The Foreign Function Interface language specification
+ (included in this manual, in <xref linkend="ffi">).</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>Foreign</literal> module (see <xref
+ linkend="sec-Foreign">) collects together several interfaces
+ which are useful in specifying foreign language
+ interfaces, including the following:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <literal>ForeignObj</literal> module (see <xref
+ linkend="sec-ForeignObj">), for managing pointers from
+ Haskell into the outside world.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>StablePtr</literal> module (see <xref
+ linkend="sec-stable-pointers">), for managing pointers
+ into Haskell from the outside world.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>CTypes</literal> module (see <xref
+ linkend="sec-CTypes">) gives Haskell equivalents for the
+ standard C datatypes, for use in making Haskell bindings
+ to existing C libraries.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>CTypesISO</literal> module (see <xref
+ linkend="sec-CTypesISO">) gives Haskell equivalents for C
+ types defined by the ISO C standard.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>Storable</literal> library, for
+ primitive marshalling of data types between Haskell and
+ the foreign language.</para>
+ </listitem>
+ </itemizedlist>
+
+ </listitem>
+ </itemizedlist>
+
+<para>The following sections also give some hints and tips on the use
+of the foreign function interface in GHC.</para>
<Sect2 id="glasgow-foreign-headers">
<Title>Using function headers
<Para>
<ProgramListing>
-typedef unsigned long *StgForeignObj;
-typedef long StgInt;
-
-void initialiseEFS (StgInt size);
-StgInt terminateEFS (void);
-StgForeignObj emptyEFS(void);
-StgForeignObj updateEFS (StgForeignObj a, StgInt i, StgInt x);
-StgInt lookupEFS (StgForeignObj a, StgInt i);
-</ProgramListing>
-
-</Para>
-
-<Para>
-You can find appropriate definitions for <Literal>StgInt</Literal>, <Literal>StgForeignObj</Literal>,
-etc using <Command>gcc</Command> on your architecture by consulting
-<Filename>ghc/includes/StgTypes.h</Filename>. The following table summarises the
-relationship between Haskell types and C types.
-</Para>
-
-<Para>
-
-<InformalTable>
-<TGroup Cols="2">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>C type name</Emphasis> </Entry>
-<Entry> <Emphasis>Haskell Type</Emphasis> </Entry>
-</Row>
-
-<Row>
-<Entry>
-<Literal>StgChar</Literal> </Entry>
-<Entry> <Literal>Char#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgInt</Literal> </Entry>
-<Entry> <Literal>Int#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgWord</Literal> </Entry>
-<Entry> <Literal>Word#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgAddr</Literal> </Entry>
-<Entry> <Literal>Addr#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgFloat</Literal> </Entry>
-<Entry> <Literal>Float#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgDouble</Literal> </Entry>
-<Entry> <Literal>Double#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>Array#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>ByteArray#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgArray</Literal> </Entry>
-<Entry> <Literal>MutableArray#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgByteArray</Literal> </Entry>
-<Entry> <Literal>MutableByteArray#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgStablePtr</Literal> </Entry>
-<Entry> <Literal>StablePtr#</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StgForeignObj</Literal> </Entry>
-<Entry> <Literal>ForeignObj#</Literal></Entry>
-</Row>
-</TBody>
-
-</TGroup>
-</InformalTable>
-</Para>
-
-<Para>
-Note that this approach is only <Emphasis>essential</Emphasis> for returning
-<Literal>float</Literal>s (or if <Literal>sizeof(int) != sizeof(int *)</Literal> on your
-architecture) but is a Good Thing for anyone who cares about writing
-solid code. You're crazy not to do it.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-stablePtrs">
-<Title>Subverting automatic unboxing with “stable pointers”
-</Title>
-
-<Para>
-<IndexTerm><Primary>stable pointers (Glasgow extension)</Primary></IndexTerm>
-</Para>
-
-<Para>
-The arguments of a <Function>_ccall_</Function> automatically unboxed before the
-call. There are two reasons why this is usually the Right Thing to
-do:
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<Para>
-C is a strict language: it would be excessively tedious to pass
-unevaluated arguments and require the C programmer to force their
-evaluation before using them.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Boxed values are stored on the Haskell heap and may be moved
-within the heap if a garbage collection occurs—that is, pointers
-to boxed objects are not <Emphasis>stable</Emphasis>.
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-</Para>
-
-<Para>
-It is possible to subvert the unboxing process by creating a “stable
-pointer” to a value and passing the stable pointer instead. For
-example, to pass/return an integer lazily to C functions <Function>storeC</Function> and
-<Function>fetchC</Function> might write:
-</Para>
-
-<Para>
-
-<ProgramListing>
-storeH :: Int -> IO ()
-storeH x = makeStablePtr x >>= \ stable_x ->
- _ccall_ storeC stable_x
-
-fetchH :: IO Int
-fetchH x = _ccall_ fetchC >>= \ stable_x ->
- deRefStablePtr stable_x >>= \ x ->
- freeStablePtr stable_x >>
- return x
-</ProgramListing>
-
-</Para>
-
-<Para>
-The garbage collector will refrain from throwing a stable pointer away
-until you explicitly call one of the following from C or Haskell.
-</Para>
-
-<Para>
-
-<ProgramListing>
-void freeStablePointer( StgStablePtr stablePtrToToss )
-freeStablePtr :: StablePtr a -> IO ()
-</ProgramListing>
-
-</Para>
-
-<Para>
-As with the use of <Function>free</Function> in C programs, GREAT CARE SHOULD BE
-EXERCISED to ensure these functions are called at the right time: too
-early and you get dangling references (and, if you're lucky, an error
-message from the runtime system); too late and you get space leaks.
-</Para>
-
-<Para>
-And to force evaluation of the argument within <Function>fooC</Function>, one would
-call one of the following C functions (according to type of argument).
-</Para>
-
-<Para>
-
-<ProgramListing>
-void performIO ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
-StgInt enterInt ( StgStablePtr stableIndex /* StablePtr s Int */ );
-StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
-</ProgramListing>
-
-</Para>
-
-<Para>
-<IndexTerm><Primary>performIO</Primary></IndexTerm>
-<IndexTerm><Primary>enterInt</Primary></IndexTerm>
-<IndexTerm><Primary>enterFloat</Primary></IndexTerm>
-</Para>
+#include "HsFFI.h"
-<Para>
-Nota Bene: <Function>_ccall_GC_</Function><IndexTerm><Primary>_ccall_GC_</Primary></IndexTerm> must be used if any of
-these functions are used.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-foreignObjs">
-<Title>Foreign objects: pointing outside the Haskell heap
-</Title>
-
-<Para>
-<IndexTerm><Primary>foreign objects (Glasgow extension)</Primary></IndexTerm>
-</Para>
-
-<Para>
-There are two types that GHC programs can use to reference
-(heap-allocated) objects outside the Haskell world: <Literal>Addr</Literal> and
-<Literal>ForeignObj</Literal>.
-</Para>
-
-<Para>
-If you use <Literal>Addr</Literal>, it is up to you to the programmer to arrange
-allocation and deallocation of the objects.
-</Para>
-
-<Para>
-If you use <Literal>ForeignObj</Literal>, GHC's garbage collector will call upon the
-user-supplied <Emphasis>finaliser</Emphasis> function to free the object when the
-Haskell world no longer can access the object. (An object is
-associated with a finaliser function when the abstract
-Haskell type <Literal>ForeignObj</Literal> is created). The finaliser function is
-expressed in C, and is passed as argument the object:
-</Para>
-
-<Para>
-
-<ProgramListing>
-void foreignFinaliser ( StgForeignObj fo )
+void initialiseEFS (HsInt size);
+HsInt terminateEFS (void);
+HsForeignObj emptyEFS(void);
+HsForeignObj updateEFS (HsForeignObj a, HsInt i, HsInt x);
+HsInt lookupEFS (HsForeignObj a, HsInt i);
</ProgramListing>
-
</Para>
-<Para>
-when the Haskell world can no longer access the object. Since
-<Literal>ForeignObj</Literal>s only get released when a garbage collection occurs, we
-provide ways of triggering a garbage collection from within C and from
-within Haskell.
-</Para>
-
-<Para>
-
-<ProgramListing>
-void GarbageCollect()
-performGC :: IO ()
-</ProgramListing>
+ <para>The types <literal>HsInt</literal>,
+ <literal>HsForeignObj</literal> etc. are described in <xref
+ linkend="sec-mapping-table">.</Para>
-</Para>
-
-<Para>
-More information on the programmers' interface to <Literal>ForeignObj</Literal> can be
-found in the library documentation.
-</Para>
-
-</Sect2>
-
-<Sect2 id="glasgow-avoiding-monads">
-<Title>Avoiding monads
-</Title>
-
-<Para>
-<IndexTerm><Primary>C calls to `pure C'</Primary></IndexTerm>
-<IndexTerm><Primary>unsafePerformIO</Primary></IndexTerm>
-</Para>
-
-<Para>
-The <Function>_ccall_</Function> construct is part of the <Literal>IO</Literal> monad because 9 out of 10
-uses will be to call imperative functions with side effects such as
-<Function>printf</Function>. Use of the monad ensures that these operations happen in a
-predictable order in spite of laziness and compiler optimisations.
-</Para>
-
-<Para>
-To avoid having to be in the monad to call a C function, it is
-possible to use <Function>unsafePerformIO</Function>, which is available from the
-<Literal>IOExts</Literal> module. There are three situations where one might like to
-call a C function from outside the IO world:
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<Para>
-Calling a function with no side-effects:
-
-<ProgramListing>
-atan2d :: Double -> Double -> Double
-atan2d y x = unsafePerformIO (_ccall_ atan2d y x)
-
-sincosd :: Double -> (Double, Double)
-sincosd x = unsafePerformIO $ do
- da <- newDoubleArray (0, 1)
- _casm_ “sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );” x da
- s <- readDoubleArray da 0
- c <- readDoubleArray da 1
- return (s, c)
-</ProgramListing>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Calling a set of functions which have side-effects but which can
-be used in a purely functional manner.
-
-For example, an imperative implementation of a purely functional
-lookup-table might be accessed using the following functions.
-
-
-<ProgramListing>
-empty :: EFS x
-update :: EFS x -> Int -> x -> EFS x
-lookup :: EFS a -> Int -> a
-
-empty = unsafePerformIO (_ccall_ emptyEFS)
-
-update a i x = unsafePerformIO $
- makeStablePtr x >>= \ stable_x ->
- _ccall_ updateEFS a i stable_x
-
-lookup a i = unsafePerformIO $
- _ccall_ lookupEFS a i >>= \ stable_x ->
- deRefStablePtr stable_x
-</ProgramListing>
-
-
-You will almost always want to use <Literal>ForeignObj</Literal>s with this.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Calling a side-effecting function even though the results will
-be unpredictable. For example the <Function>trace</Function> function is defined by:
-
-
-<ProgramListing>
-trace :: String -> a -> a
-trace string expr
- = unsafePerformIO (
- ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ()) >>
- fputs sTDERR string >>
- ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) >>
- return expr )
- where
- sTDERR = (“stderr” :: Addr)
-</ProgramListing>
-
-
-(This kind of use is not highly recommended—it is only really
-useful in debugging code.)
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-</Para>
-
-</Sect2>
-
-<Sect2 id="ccall-gotchas">
-<Title>C-calling “gotchas” checklist
-</Title>
-
-<Para>
-<IndexTerm><Primary>C call dangers</Primary></IndexTerm>
-<IndexTerm><Primary>CCallable</Primary></IndexTerm>
-<IndexTerm><Primary>CReturnable</Primary></IndexTerm>
-</Para>
-
-<Para>
-And some advice, too.
-</Para>
-
-<Para>
-
-<ItemizedList>
-<ListItem>
-
-<Para>
- For modules that use <Function>_ccall_</Function>s, etc., compile with
-<Option>-fvia-C</Option>.<IndexTerm><Primary>-fvia-C option</Primary></IndexTerm> You don't have to, but you should.
-
-Also, use the <Option>-#include "prototypes.h"</Option> flag (hack) to inform the C
-compiler of the fully-prototyped types of all the C functions you
-call. (<XRef LinkEnd="glasgow-foreign-headers"> says more about this…)
-
-This scheme is the <Emphasis>only</Emphasis> way that you will get <Emphasis>any</Emphasis>
-typechecking of your <Function>_ccall_</Function>s. (It shouldn't be that way, but…).
-GHC will pass the flag <Option>-Wimplicit</Option> to <Command>gcc</Command> so that you'll get warnings
-if any <Function>_ccall_</Function>ed functions have no prototypes.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
-Try to avoid <Function>_ccall_</Function>s to C functions that take <Literal>float</Literal>
-arguments or return <Literal>float</Literal> results. Reason: if you do, you will
-become entangled in (ANSI?) C's rules for when arguments/results are
-promoted to <Literal>doubles</Literal>. It's a nightmare and just not worth it.
-Use <Literal>doubles</Literal> if possible.
-
-If you do use <Literal>floats</Literal>, check and re-check that the right thing is
-happening. Perhaps compile with <Option>-keep-hc-file-too</Option> and look at
-the intermediate C (<Function>.hc</Function>).
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- The compiler uses two non-standard type-classes when
-type-checking the arguments and results of <Function>_ccall_</Function>: the arguments
-(respectively result) of <Function>_ccall_</Function> must be instances of the class
-<Literal>CCallable</Literal> (respectively <Literal>CReturnable</Literal>). Both classes may be
-imported from the module <Literal>CCall</Literal>, but this should only be
-necessary if you want to define a new instance. (Neither class
-defines any methods—their only function is to keep the
-type-checker happy.)
-
-The type checker must be able to figure out just which of the
-C-callable/returnable types is being used. If it can't, you have to
-add type signatures. For example,
-
-
-<ProgramListing>
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-is not good enough, because the compiler can't work out what type <VarName>x</VarName>
-is, nor what type the <Function>_ccall_</Function> returns. You have to write, say:
-
-
-<ProgramListing>
-f :: Int -> IO Double
-f x = _ccall_ foo x
-</ProgramListing>
-
-
-This table summarises the standard instances of these classes.
-
-<InformalTable>
-<TGroup Cols="4">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
-<TBody>
-<Row>
-<Entry><Emphasis>Type</Emphasis> </Entry>
-<Entry><Emphasis>CCallable</Emphasis></Entry>
-<Entry><Emphasis>CReturnable</Emphasis> </Entry>
-<Entry><Emphasis>Which is probably…</Emphasis> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Char</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned char</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Int</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Word</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long int</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Addr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Float</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>float</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Double</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>double</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>()</Literal> </Entry>
-<Entry> No </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>void</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>[Char]</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>char *</Literal> (null-terminated) </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>Array</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>MutableByteArray</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> No </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>State</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> nothing!</Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>StablePtr</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> <Literal>unsigned long *</Literal> </Entry>
-</Row>
-<Row>
-<Entry>
-<Literal>ForeignObjs</Literal> </Entry>
-<Entry> Yes </Entry>
-<Entry> Yes </Entry>
-<Entry> see later </Entry>
-</Row>
-
-</TBody>
-
-</TGroup>
-</InformalTable>
-
-Actually, the <Literal>Word</Literal> type is defined as being the same size as a
-pointer on the target architecture, which is <Emphasis>probably</Emphasis>
-<Literal>unsigned long int</Literal>.
-
-The brave and careful programmer can add their own instances of these
-classes for the following types:
-
-
-<ItemizedList>
-<ListItem>
-
-<Para>
-A <Emphasis>boxed-primitive</Emphasis> type may be made an instance of both
-<Literal>CCallable</Literal> and <Literal>CReturnable</Literal>.
-
-A boxed primitive type is any data type with a
-single unary constructor with a single primitive argument. For
-example, the following are all boxed primitive types:
-
-
-<ProgramListing>
-Int
-Double
-data XDisplay = XDisplay Addr#
-data EFS a = EFS# ForeignObj#
-</ProgramListing>
-
-
-
-<ProgramListing>
-instance CCallable (EFS a)
-instance CReturnable (EFS a)
-</ProgramListing>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- Any datatype with a single nullary constructor may be made an
-instance of <Literal>CReturnable</Literal>. For example:
-
-
-<ProgramListing>
-data MyVoid = MyVoid
-instance CReturnable MyVoid
-</ProgramListing>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- As at version 2.09, <Literal>String</Literal> (i.e., <Literal>[Char]</Literal>) is still
-not a <Literal>CReturnable</Literal> type.
-
-Also, the now-builtin type <Literal>PackedString</Literal> is neither
-<Literal>CCallable</Literal> nor <Literal>CReturnable</Literal>. (But there are functions in
-the PackedString interface to let you get at the necessary bits…)
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- The code-generator will complain if you attempt to use <Literal>%r</Literal> in
-a <Literal>_casm_</Literal> whose result type is <Literal>IO ()</Literal>; or if you don't use <Literal>%r</Literal>
-<Emphasis>precisely</Emphasis> once for any other result type. These messages are
-supposed to be helpful and catch bugs—please tell us if they wreck
-your life.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
- If you call out to C code which may trigger the Haskell garbage
-collector or create new threads (examples of this later…), then you
-must use the <Function>_ccall_GC_</Function><IndexTerm><Primary>_ccall_GC_ primitive</Primary></IndexTerm> or
-<Function>_casm_GC_</Function><IndexTerm><Primary>_casm_GC_ primitive</Primary></IndexTerm> variant of C-calls. (This
-does not work with the native code generator—use <Option>-fvia-C</Option>.) This
-stuff is hairy with a capital H!
-</Para>
-</ListItem>
-
-</ItemizedList>
-
-</Para>
+ <Para>Note that this approach is only
+ <Emphasis>essential</Emphasis> for returning
+ <Literal>float</Literal>s (or if <Literal>sizeof(int) !=
+ sizeof(int *)</Literal> on your architecture) but is a Good
+ Thing for anyone who cares about writing solid code. You're
+ crazy not to do it.</Para>
</Sect2>
</Title>
<Para>
-This section documents GHC's implementation of multi-paramter type
+This section documents GHC's implementation of multi-parameter type
classes. There's lots of background in the paper <ULink
-URL="http://www.dcs.gla.ac.uk/~simonpj/multi.ps.gz"
->Type classes: exploring the design space</ULink
-> (Simon Peyton
-Jones, Mark Jones, Erik Meijer).
+URL="http://research.microsoft.com/~simonpj/multi.ps.gz" >Type
+classes: exploring the design space</ULink > (Simon Peyton Jones, Mark
+Jones, Erik Meijer).
</Para>
<Para>
<Para>
Assertion failures can be caught, see the documentation for the
-Hugs/GHC Exception library for information of how.
+<literal>Exception</literal> library (<xref linkend="sec-Exception">)
+for the details.
</Para>
</Sect1>
</Sect2>
</Sect1>
+
+<!-- Emacs stuff:
+ ;;; Local Variables: ***
+ ;;; mode: sgml ***
+ ;;; sgml-parent-document: ("users_guide.sgml" "book" "chapter" "sect1") ***
+ ;;; End: ***
+ -->