X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdocs%2Fusers_guide%2Fglasgow_exts.sgml;h=779332bfb1b25ce5cbbc17796ffce3a37e8d90f8;hb=33e03e0ba6cc2cbaf17ae80ba4f9b2500b648232;hp=e1467fa69ca8354c0cdf5eca041e878028c47500;hpb=d81a27200736892424570e71001daed81df8ff84;p=ghc-hetmet.git diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml index e1467fa..779332b 100644 --- a/ghc/docs/users_guide/glasgow_exts.sgml +++ b/ghc/docs/users_guide/glasgow_exts.sgml @@ -19,103 +19,122 @@ performance because of the implementation costs of Haskell's Executive summary of our extensions: - - - - -Unboxed types and primitive operations: - - -You can get right down to the raw machine types and operations; -included in this are “primitive arrays” (direct access to Big Wads -of Bytes). Please see and following. - - - - - -Multi-parameter type classes: - - -GHC's type system supports extended type classes with multiple -parameters. Please see . - - - - - -Local universal quantification: - - -GHC's type system supports explicit universal quantification in -constructor fields and function arguments. This is useful for things -like defining runST from the state-thread world. See . - - - - - -Extistentially quantification in data types: - - -Some or all of the type variables in a datatype declaration may be -existentially quantified. More details in . - - - - - -Scoped type variables: - - -Scoped type variables enable the programmer to supply type signatures -for some nested declarations, where this would not be legal in Haskell -98. Details in . - - - - - -Pattern guards - - -Instead of being a boolean expression, a guard is a list of qualifiers, exactly as in a list comprehension. See . - - - - - -Calling out to C: - - -Just what it sounds like. We provide lots of rope that you -can dangle around your neck. Please see . - - - - - -Pragmas - - -Pragmas are special instructions to the compiler placed in the source -file. The pragmas GHC supports are described in . - - - - - -Rewrite rules: - - -The programmer can specify rewrite rules as part of the source program -(in a pragma). GHC applies these rewrite rules wherever it can. -Details in . - - - - - + + + + Unboxed types and primitive operations: + + You can get right down to the raw machine types and + operations; included in this are “primitive + arrays” (direct access to Big Wads of Bytes). Please + see and following. + + + + + Type system extensions: + + GHC supports a large number of extensions to Haskell's + type system. Specifically: + + + + Multi-parameter type classes: + + + + + + + Functional dependencies: + + + + + + + Implicit parameters: + + + + + + + Local universal quantification: + + + + + + + Extistentially quantification in data types: + + + + + + + Scoped type variables: + + Scoped type variables enable the programmer to + supply type signatures for some nested declarations, + where this would not be legal in Haskell 98. Details in + . + + + + + + + + Pattern guards + + Instead of being a boolean expression, a guard is a list + of qualifiers, exactly as in a list comprehension. See . + + + + + Foreign calling: + + Just what it sounds like. We provide + lots of rope that you can dangle around + your neck. Please see . + + + + + Pragmas + + Pragmas are special instructions to the compiler placed + in the source file. The pragmas GHC supports are described in + . + + + + + Rewrite rules: + + The programmer can specify rewrite rules as part of the + source program (in a pragma). GHC applies these rewrite rules + wherever it can. Details in . + + + + + Generic classes: + + Generic class declarations allow you to define a class + whose methods say how to work over an arbitrary data type. + Then it's really easy to make any new type into an instance of + the class. This generalises the rather ad-hoc "deriving" + feature of Haskell 98. Details in . + + + Before you get too carried away working at the lowest level (e.g., @@ -125,6 +144,135 @@ program), you may wish to check if there are libraries that provide a . + + Language options + + languageoption + + optionslanguage + + extensionsoptions controlling + + + These flags control what variation of the language are + permitted. Leaving out all of them gives you standard Haskell + 98. + + + + + : + + + This simultaneously enables all of the extensions to + Haskell 98 described in , except where otherwise + noted. + + + + + : + + + Switch off the Haskell 98 monomorphism restriction. + Independent of the + flag. + + + + + + + + + + + + See . Only relevant + if you also use . + + + + + + + + See . Only relevant if + you also use . + + + + + + + + See . Independent of + . + + + + + + + -fno-implicit-prelude + option GHC normally imports + Prelude.hi files for you. If you'd + rather it didn't, then give it a + option. The idea + is that you can then import a Prelude of your own. (But + don't call it Prelude; the Haskell + module namespace is flat, and you must not conflict with + any Prelude module.) + + Even though you have not imported the Prelude, all + the built-in syntax still refers to the built-in Haskell + Prelude types and values, as specified by the Haskell + Report. For example, the type [Int] + still means Prelude.[] Int; tuples + continue to refer to the standard Prelude tuples; the + translation for list comprehensions continues to use + Prelude.map etc. + + With one group of exceptions! You may want to + define your own numeric class hierarchy. It completely + defeats that purpose if the literal "1" means + "Prelude.fromInteger 1", which is what + the Haskell Report specifies. So the + flag causes the + following pieces of built-in syntax to refer to whatever + is in scope, not the Prelude versions: + + + + Integer and fractional literals mean + "fromInteger 1" and + "fromRational 3.2", not the + Prelude-qualified versions; both in expressions and in + patterns. + + + + Negation (e.g. "- (f x)") + means "negate (f x)" (not + Prelude.negate). + + + + In an n+k pattern, the standard Prelude + Ord class is used for comparison, + but the necessary subtraction uses whatever + "(-)" is in scope (not + "Prelude.(-)"). + + + + + + + + + Unboxed types and primitive operations @@ -309,8 +457,8 @@ Note: we may relax some of these restrictions in the future. -The IO and ST monads use unboxed tuples to avoid unnecessary -allocation during sequences of operations. +The IO and ST monads use unboxed +tuples to avoid unnecessary allocation during sequences of operations. @@ -318,16 +466,14 @@ allocation during sequences of operations. Character and numeric types - character types, primitive numeric types, primitive integer types, primitive floating point types, primitive + There are the following obvious primitive types: - - type Char# type Int# @@ -347,7 +493,6 @@ type Word64# Double# Int64# Word64# - If you really want to know their exact equivalents in C, see @@ -364,8 +509,8 @@ Literals for these types may be written as follows: 1# an Int# 1.2# a Float# 1.34## a Double# -'a'# a Char#; for weird characters, use '\o<octal>'# -"a"# an Addr# (a `char *') +'a'# a Char#; for weird characters, use e.g. '\o<octal>'# +"a"# an Addr# (a `char *'); only characters '\0'..'\255' allowed literals, primitive @@ -1318,7 +1463,7 @@ C. -Please see for more details. +Please see for more details. @@ -1334,7 +1479,7 @@ memory when you're done with it.” -Please see for more details. +Please see for more details. @@ -1354,983 +1499,226 @@ The libraries documentatation gives more details on all these Pattern guards (Glasgow extension) -The discussion that follows is an abbreviated version of Simon Peyton Jones's original proposal. (Note that the proposal was written before pattern guards were implemented, so refers to them as unimplemented.) - - - -Suppose we have an abstract data type of finite maps, with a -lookup operation: - - -lookup :: FiniteMap -> Int -> Maybe Int - - -The lookup returns Nothing if the supplied key is not in the domain of the mapping, and (Just v) otherwise, -where v is the value that the key maps to. Now consider the following definition: - - - -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 - - - -The auxiliary functions are - - - -maybeToBool :: Maybe a -> Bool -maybeToBool (Just x) = True -maybeToBool Nothing = False - -expectJust :: Maybe a -> a -expectJust (Just x) = x -expectJust Nothing = error "Unexpected Nothing" - - - -What is clunky doing? The guard ok1 && -ok2 checks that both lookups succeed, using -maybeToBool to convert the Maybe -types to booleans. The (lazily evaluated) expectJust -calls extract the values from the results of the lookups, and binds the -returned values to val1 and val2 -respectively. If either lookup fails, then clunky takes the -otherwise case and returns the sum of its arguments. - - - -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: - - - -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 - - - -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 (fail), and the whole expression -tends to become more and more indented. - - - -Here is how I would write clunky: - - - -clunky env var1 var1 - | Just val1 <- lookup env var1 - , Just val2 <- lookup env var2 - = val1 + val2 -...other equations for clunky... - - - -The semantics should be clear enough. The qualifers are matched in order. -For a <- 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 -<- 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. - - - -Just as with list comprehensions, boolean expressions can be freely mixed -with among the pattern guards. For example: - - - -f x | [y] <- x - , y > 3 - , Just z <- h y - = ... - - - -Haskell's current guards therefore emerge as a special case, in which the -qualifier list has just one element, a boolean expression. - - - - - -Calling C directly from Haskell - - -C calls (Glasgow extension) -_ccall_ (Glasgow extension) -_casm_ (Glasgow extension) -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. - - - -<Function>_ccall_</Function> and <Function>_casm_</Function>: an introduction - - - -The simplest way to use a simple C function - - - - - -double fooC( FILE *in, char c, int i, double d, unsigned int u ) - - - - - -is to provide a Haskell wrapper: - - - - - -fooH :: Char -> Int -> Double -> Word -> IO Double -fooH c i d w = _ccall_ fooC (“stdin”::Addr) c i d w - - - - - -The function fooH unbox all of its arguments, call the C -function fooC and box the corresponding arguments. - - - -One of the annoyances about _ccall_s is when the C types don't quite -match the Haskell compiler's ideas. For this, the _casm_ variant -may be just the ticket (NB: no chance of such code going -through a native-code generator): - - - - - -import Addr -import CString - -oldGetEnv name - = _casm_ “%r = getenv((char *) %0);” name >>= \ litstring -> - return ( - if (litstring == nullAddr) then - Left ("Fail:oldGetEnv:"++name) - else - Right (unpackCString litstring) - ) - - - - - -The first literal-literal argument to a _casm_ is like a printf -format: %r is replaced with the “result,” %0%n-1 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 _ccall_ goes -for _casm_ as well. - - - -The use of _casm_ 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 _casm_, its unfolding will not 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 _casm_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 _casm_, 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 _casm_ 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. - - - -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 - will turn off the default behaviour. --funfold-casms-in-hi-file option - - - - - -Literal-literals - - -Literal-literals -The literal-literal argument to _casm_ can be made use of separately -from the _casm_ construct itself. Indeed, we've already used it: - - - - - -fooH :: Char -> Int -> Double -> Word -> IO Double -fooH c i d w = _ccall_ fooC (“stdin”::Addr) c i d w - - - - - -The first argument that's passed to fooC is given as a literal-literal, -that is, a literal chunk of C code that will be inserted into the generated -.hc code at the right place. - - - -A literal-literal is restricted to having a type that's an instance of -the CCallable class, see -for more information. - - - -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. - - - - - -Using function headers - - - -C calls, function headers - - - -When generating C (using the directive), one can assist the -C compiler in detecting type errors by using the -#include directive -to provide .h files containing function headers. - - - -For example, - - - - - -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); - - - - - -You can find appropriate definitions for StgInt, StgForeignObj, -etc using gcc on your architecture by consulting -ghc/includes/StgTypes.h. The following table summarises the -relationship between Haskell types and C types. - - - - - - - - - - -C type name - Haskell Type - - - - -StgChar - Char# - - - -StgInt - Int# - - - -StgWord - Word# - - - -StgAddr - Addr# - - - -StgFloat - Float# - - - -StgDouble - Double# - - - -StgArray - Array# - - - -StgByteArray - ByteArray# - - - -StgArray - MutableArray# - - - -StgByteArray - MutableByteArray# - - - -StgStablePtr - StablePtr# - - - -StgForeignObj - ForeignObj# - - - - - - - - -Note that this approach is only essential for returning -floats (or if sizeof(int) != sizeof(int *) on your -architecture) but is a Good Thing for anyone who cares about writing -solid code. You're crazy not to do it. - - - - - -Subverting automatic unboxing with “stable pointers” - - - -stable pointers (Glasgow extension) - - - -The arguments of a _ccall_ automatically unboxed before the -call. There are two reasons why this is usually the Right Thing to -do: - - - - - - - - -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. - - - - - - - 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 stable. - - - - - - - - -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 storeC and -fetchC might write: - - - - - -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 - - - - - -The garbage collector will refrain from throwing a stable pointer away -until you explicitly call one of the following from C or Haskell. - - - - - -void freeStablePointer( StgStablePtr stablePtrToToss ) -freeStablePtr :: StablePtr a -> IO () - - - - - -As with the use of free 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. - - - -And to force evaluation of the argument within fooC, one would -call one of the following C functions (according to type of argument). - - - - - -void performIO ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ ); -StgInt enterInt ( StgStablePtr stableIndex /* StablePtr s Int */ ); -StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ ); - - - - - -performIO -enterInt -enterFloat - - - -Nota Bene: _ccall_GC__ccall_GC_ must be used if any of -these functions are used. - - - - - -Foreign objects: pointing outside the Haskell heap - - - -foreign objects (Glasgow extension) - - - -There are two types that GHC programs can use to reference -(heap-allocated) objects outside the Haskell world: Addr and -ForeignObj. - - - -If you use Addr, it is up to you to the programmer to arrange -allocation and deallocation of the objects. - - - -If you use ForeignObj, GHC's garbage collector will call upon the -user-supplied finaliser 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 ForeignObj is created). The finaliser function is -expressed in C, and is passed as argument the object: - - - - - -void foreignFinaliser ( StgForeignObj fo ) - - - - - -when the Haskell world can no longer access the object. Since -ForeignObjs only get released when a garbage collection occurs, we -provide ways of triggering a garbage collection from within C and from -within Haskell. - - - - - -void GarbageCollect() -performGC :: IO () - - - - - -More information on the programmers' interface to ForeignObj can be -found in the library documentation. - - - - - -Avoiding monads - - - -C calls to `pure C' -unsafePerformIO - - - -The _ccall_ construct is part of the IO monad because 9 out of 10 -uses will be to call imperative functions with side effects such as -printf. Use of the monad ensures that these operations happen in a -predictable order in spite of laziness and compiler optimisations. - - - -To avoid having to be in the monad to call a C function, it is -possible to use unsafePerformIO, which is available from the -IOExts module. There are three situations where one might like to -call a C function from outside the IO world: - - - - - - - - -Calling a function with no side-effects: - - -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) - - - - - - - - - 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. - - - -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 - - - -You will almost always want to use ForeignObjs with this. - - - - - - - Calling a side-effecting function even though the results will -be unpredictable. For example the trace function is defined by: - - - -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) - - - -(This kind of use is not highly recommended—it is only really -useful in debugging code.) - - - - - - - - - - -C-calling “gotchas” checklist - - - -C call dangers -CCallable -CReturnable - - - -And some advice, too. - - - - - - - - - For modules that use _ccall_s, etc., compile with -.-fvia-C option You don't have to, but you should. - -Also, use the flag (hack) to inform the C -compiler of the fully-prototyped types of all the C functions you -call. ( says more about this…) - -This scheme is the only way that you will get any -typechecking of your _ccall_s. (It shouldn't be that way, but…). -GHC will pass the flag to gcc so that you'll get warnings -if any _ccall_ed functions have no prototypes. - +The discussion that follows is an abbreviated version of Simon Peyton Jones's original proposal. (Note that the proposal was written before pattern guards were implemented, so refers to them as unimplemented.) - - -Try to avoid _ccall_s to C functions that take float -arguments or return float results. Reason: if you do, you will -become entangled in (ANSI?) C's rules for when arguments/results are -promoted to doubles. It's a nightmare and just not worth it. -Use doubles if possible. +Suppose we have an abstract data type of finite maps, with a +lookup operation: -If you do use floats, check and re-check that the right thing is -happening. Perhaps compile with and look at -the intermediate C (.hc). + +lookup :: FiniteMap -> Int -> Maybe Int + +The lookup returns Nothing if the supplied key is not in the domain of the mapping, and (Just v) otherwise, +where v is the value that the key maps to. Now consider the following definition: - - + + +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 + - The compiler uses two non-standard type-classes when -type-checking the arguments and results of _ccall_: the arguments -(respectively result) of _ccall_ must be instances of the class -CCallable (respectively CReturnable). Both classes may be -imported from the module CCall, 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, - - - -f x = _ccall_ foo x - - - -is not good enough, because the compiler can't work out what type x -is, nor what type the _ccall_ returns. You have to write, say: - - - -f :: Int -> IO Double -f x = _ccall_ foo x - - - -This table summarises the standard instances of these classes. - - - - - - - - - -Type -CCallable -CReturnable -Which is probably… - - - -Char - Yes - Yes - unsigned char - - - -Int - Yes - Yes - long int - - - -Word - Yes - Yes - unsigned long int - - - -Addr - Yes - Yes - void * - - - -Float - Yes - Yes - float - - - -Double - Yes - Yes - double - - - -() - No - Yes - void - - - -[Char] - Yes - No - char * (null-terminated) - - - -Array - Yes - No - unsigned long * - - - -ByteArray - Yes - No - unsigned long * - - - -MutableArray - Yes - No - unsigned long * - - - -MutableByteArray - Yes - No - unsigned long * - - - -State - Yes - Yes - nothing! - - - -StablePtr - Yes - Yes - unsigned long * - - - -ForeignObjs - Yes - Yes - see later - - - - - - - -Actually, the Word type is defined as being the same size as a -pointer on the target architecture, which is probably -unsigned long int. - -The brave and careful programmer can add their own instances of these -classes for the following types: +The auxiliary functions are + + +maybeToBool :: Maybe a -> Bool +maybeToBool (Just x) = True +maybeToBool Nothing = False - - +expectJust :: Maybe a -> a +expectJust (Just x) = x +expectJust Nothing = error "Unexpected Nothing" + -A boxed-primitive type may be made an instance of both -CCallable and CReturnable. - -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: +What is clunky doing? The guard ok1 && +ok2 checks that both lookups succeed, using +maybeToBool to convert the Maybe +types to booleans. The (lazily evaluated) expectJust +calls extract the values from the results of the lookups, and binds the +returned values to val1 and val2 +respectively. If either lookup fails, then clunky takes the +otherwise case and returns the sum of its arguments. + + +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: + -Int -Double -data XDisplay = XDisplay Addr# -data EFS a = EFS# ForeignObj# +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 + +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 (fail), and the whole expression +tends to become more and more indented. + + +Here is how I would write clunky: + -instance CCallable (EFS a) -instance CReturnable (EFS a) +clunky env var1 var1 + | Just val1 <- lookup env var1 + , Just val2 <- lookup env var2 + = val1 + val2 +...other equations for clunky... - + +The semantics should be clear enough. The qualifers are matched in order. +For a <- 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 +<- 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. - - - Any datatype with a single nullary constructor may be made an -instance of CReturnable. For example: - +Just as with list comprehensions, boolean expressions can be freely mixed +with among the pattern guards. For example: + -data MyVoid = MyVoid -instance CReturnable MyVoid +f x | [y] <- x + , y > 3 + , Just z <- h y + = ... - - - - - - As at version 2.09, String (i.e., [Char]) is still -not a CReturnable type. - -Also, the now-builtin type PackedString is neither -CCallable nor CReturnable. (But there are functions in -the PackedString interface to let you get at the necessary bits…) +Haskell's current guards therefore emerge as a special case, in which the +qualifier list has just one element, a boolean expression. - + - + + The foreign interface + + The foreign interface consists of the following components: + + + + The Foreign Function Interface language specification + (included in this manual, in ). + + + + The Foreign module (see ) collects together several interfaces + which are useful in specifying foreign language + interfaces, including the following: + + + + The ForeignObj module (see ), for managing pointers from + Haskell into the outside world. + + + + The StablePtr module (see ), for managing pointers + into Haskell from the outside world. + + + + The CTypes module (see ) gives Haskell equivalents for the + standard C datatypes, for use in making Haskell bindings + to existing C libraries. + + + + The CTypesISO module (see ) gives Haskell equivalents for C + types defined by the ISO C standard. + + + + The Storable library, for + primitive marshalling of data types between Haskell and + the foreign language. + + + + + + +The following sections also give some hints and tips on the use +of the foreign function interface in GHC. + +Using function headers + + +C calls, function headers - - - The code-generator will complain if you attempt to use %r in -a _casm_ whose result type is IO (); or if you don't use %r -precisely once for any other result type. These messages are -supposed to be helpful and catch bugs—please tell us if they wreck -your life. - +When generating C (using the directive), one can assist the +C compiler in detecting type errors by using the -#include directive +to provide .h files containing function headers. - - - 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 _ccall_GC__ccall_GC_ primitive or -_casm_GC__casm_GC_ primitive variant of C-calls. (This -does not work with the native code generator—use .) This -stuff is hairy with a capital H! +For example, - - + + + +#include "HsFFI.h" +void initialiseEFS (HsInt size); +HsInt terminateEFS (void); +HsForeignObj emptyEFS(void); +HsForeignObj updateEFS (HsForeignObj a, HsInt i, HsInt x); +HsInt lookupEFS (HsForeignObj a, HsInt i); + + The types HsInt, + HsForeignObj etc. are described in . + + Note that this approach is only + essential for returning + floats (or if sizeof(int) != + sizeof(int *) on your architecture) but is a Good + Thing for anyone who cares about writing solid code. You're + crazy not to do it. + @@ -2340,7 +1728,7 @@ stuff is hairy with a capital H! -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 Type classes: exploring the design space (Simon Peyton Jones, Mark @@ -2640,7 +2028,7 @@ class like this: - + Instance declarations @@ -2892,13 +2280,64 @@ with N. + +Implicit parameters + + + Implicit paramters are implemented as described in +"Implicit parameters: dynamic scoping with static types", +J Lewis, MB Shields, E Meijer, J Launchbury, +27th ACM Symposium on Principles of Programming Languages (POPL'00), +Boston, Jan 2000. + + + +There should be more documentation, but there isn't (yet). Yell if you need it. + + + + You can't have an implicit parameter in the context of a class or instance +declaration. For example, both these declarations are illegal: + + class (?x::Int) => C a where ... + instance (?x::a) => Foo [a] where ... + +Reason: exactly which implicit parameter you pick up depends on exactly where +you invoke a function. But the ``invocation'' of instance declarations is done +behind the scenes by the compiler, so it's hard to figure out exactly where it is done. +Easiest thing is to outlaw the offending types. + + + + + + + + +Functional dependencies + + + Functional dependencies are implemented as described by Mark Jones +in "Type Classes with Functional Dependencies", Mark P. Jones, +In Proceedings of the 9th European Symposium on Programming, +ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782. + + + +There should be more documentation, but there isn't (yet). Yell if you need it. + + + + Explicit universal quantification -GHC now allows you to write explicitly quantified types. GHC's -syntax for this now agrees with Hugs's, namely: +GHC's type system supports explicit universal quantification in +constructor fields and function arguments. This is useful for things +like defining runST from the state-thread world. +GHC's syntax for this now agrees with Hugs's, namely: @@ -3680,7 +3119,7 @@ use of assert in the user's source: kelvinToC :: Double -> Double -kelvinToC k = assert (k &gt;= 0.0) (k+273.15) +kelvinToC k = assert (k >= 0.0) (k+273.15) @@ -4512,7 +3951,7 @@ to arbitrary expressions. For example, this is not OK: "wrong2" forall f. f True = True -In "wrong1", the LHS is not an application; in "wrong1", the LHS has a pattern variable +In "wrong1", the LHS is not an application; in "wrong2", the LHS has a pattern variable in the head. @@ -4977,6 +4416,256 @@ program even if fusion doesn't happen. More rules in PrelList.lhs + +Generic classes + + +The ideas behind this extension are described in detail in "Derivable type classes", +Ralf Hinze and Simon Peyton Jones, Haskell Workshop, Montreal Sept 2000, pp94-105. +An example will give the idea: + + + + import Generics + + class Bin a where + toBin :: a -> [Int] + fromBin :: [Int] -> (a, [Int]) + + toBin {| Unit |} Unit = [] + toBin {| a :+: b |} (Inl x) = 0 : toBin x + toBin {| a :+: b |} (Inr y) = 1 : toBin y + toBin {| a :*: b |} (x :*: y) = toBin x ++ toBin y + + fromBin {| Unit |} bs = (Unit, bs) + fromBin {| a :+: b |} (0:bs) = (Inl x, bs') where (x,bs') = fromBin bs + fromBin {| a :+: b |} (1:bs) = (Inr y, bs') where (y,bs') = fromBin bs + fromBin {| a :*: b |} bs = (x :*: y, bs'') where (x,bs' ) = fromBin bs + (y,bs'') = fromBin bs' + + +This class declaration explains how toBin and fromBin +work for arbitrary data types. They do so by giving cases for unit, product, and sum, +which are defined thus in the library module Generics: + + + data Unit = Unit + data a :+: b = Inl a | Inr b + data a :*: b = a :*: b + + +Now you can make a data type into an instance of Bin like this: + + instance (Bin a, Bin b) => Bin (a,b) + instance Bin a => Bin [a] + +That is, just leave off the "where" clasuse. Of course, you can put in the +where clause and over-ride whichever methods you please. + + + + Using generics + To use generics you need to + + + Use the flag. + + + Import the module Generics from the + lang package. This import brings into + scope the data types Unit, + :*:, and :+:. (You + don't need this import if you don't mention these types + explicitly; for example, if you are simply giving instance + declarations.) + + + + + Changes wrt the paper + +Note that the type constructors :+: and :*: +can be written infix (indeed, you can now use +any operator starting in a colon as an infix type constructor). Also note that +the type constructors are not exactly as in the paper (Unit instead of 1, etc). +Finally, note that the syntax of the type patterns in the class declaration +uses "{|" and "{|" brackets; curly braces +alone would ambiguous when they appear on right hand sides (an extension we +anticipate wanting). + + + + Terminology and restrictions + +Terminology. A "generic default method" in a class declaration +is one that is defined using type patterns as above. +A "polymorphic default method" is a default method defined as in Haskell 98. +A "generic class declaration" is a class declaration with at least one +generic default method. + + + +Restrictions: + + + +Alas, we do not yet implement the stuff about constructor names and +field labels. + + + + + +A generic class can have only one parameter; you can't have a generic +multi-parameter class. + + + + + +A default method must be defined entirely using type patterns, or entirely +without. So this is illegal: + + class Foo a where + op :: a -> (a, Bool) + op {| Unit |} Unit = (Unit, True) + op x = (x, False) + +However it is perfectly OK for some methods of a generic class to have +generic default methods and others to have polymorphic default methods. + + + + + +The type variable(s) in the type pattern for a generic method declaration +scope over the right hand side. So this is legal (note the use of the type variable ``p'' in a type signature on the right hand side: + + class Foo a where + op :: a -> Bool + op {| p :*: q |} (x :*: y) = op (x :: p) + ... + + + + + + +The type patterns in a generic default method must take one of the forms: + + a :+: b + a :*: b + Unit + +where "a" and "b" are type variables. Furthermore, all the type patterns for +a single type constructor (:*:, say) must be identical; they +must use the same type variables. So this is illegal: + + class Foo a where + op :: a -> Bool + op {| a :+: b |} (Inl x) = True + op {| p :+: q |} (Inr y) = False + +The type patterns must be identical, even in equations for different methods of the class. +So this too is illegal: + + class Foo a where + op1 :: a -> Bool + op {| a :*: b |} (Inl x) = True + + op2 :: a -> Bool + op {| p :*: q |} (Inr y) = False + +(The reason for this restriction is that we gather all the equations for a particular type consructor +into a single generic instance declaration.) + + + + + +A generic method declaration must give a case for each of the three type constructors. + + + + + +The type for a generic method can be built only from: + + Function arrows + Type variables + Tuples + Arbitrary types not involving type variables + +Here are some example type signatures for generic methods: + + op1 :: a -> Bool + op2 :: Bool -> (a,Bool) + op3 :: [Int] -> a -> a + op4 :: [a] -> Bool + +Here, op1, op2, op3 are OK, but op4 is rejected, because it has a type variable +inside a list. + + +This restriction is an implementation restriction: we just havn't got around to +implementing the necessary bidirectional maps over arbitrary type constructors. +It would be relatively easy to add specific type constructors, such as Maybe and list, +to the ones that are allowed. + + + + +In an instance declaration for a generic class, the idea is that the compiler +will fill in the methods for you, based on the generic templates. However it can only +do so if + + + + The instance type is simple (a type constructor applied to type variables, as in Haskell 98). + + + + + No constructor of the instance type has unboxed fields. + + + +(Of course, these things can only arise if you are already using GHC extensions.) +However, you can still give an instance declarations for types which break these rules, +provided you give explicit code to override any generic default methods. + + + + + + + +The option dumps incomprehensible stuff giving details of +what the compiler does with generic declarations. + + + + + Another example + +Just to finish with, here's another example I rather like: + + class Tag a where + nCons :: a -> Int + nCons {| Unit |} _ = 1 + nCons {| a :*: b |} _ = 1 + nCons {| a :+: b |} _ = nCons (bot::a) + nCons (bot::b) + + tag :: a -> Int + tag {| Unit |} _ = 1 + tag {| a :*: b |} _ = 1 + tag {| a :+: b |} (Inl x) = tag x + tag {| a :+: b |} (Inr y) = nCons (bot::a) + tag y + + + + +