haskell-98-tutorial-sources/0040755000106400000620000000000007121454527014414 5ustar jcpftphaskell-98-tutorial-sources/arrays.verb0100644000106400000620000003237707065471401016603 0ustar jcpftp%**A Gentle Introduction to Haskell: Arrays %**~header \section{Arrays} Ideally, arrays in a functional language would be regarded simply as functions from indices to values, but pragmatically, in order to assure efficient access to array elements, we need to be sure we can take advantage of the special properties of the domains of these functions, which are isomorphic to finite contiguous subsets of the integers. Haskell, therefore, does not treat arrays as general functions with an application operation, but as abstract data types with a subscript operation. Two main approaches to functional arrays may be discerned: {\em incremental} and {\em monolithic} definition. In the incremental case, we have a function that produces an empty array of a given size and another that takes an array, an index, and a value, producing a new array that differs from the old one only at the given index. Obviously, a naive implementation of such an array semantics would be intolerably inefficient, either requiring a new copy of an array for each incremental redefinition, or taking linear time for array lookup; thus, serious attempts at using this approach employ sophisticated static analysis and clever run-time devices to avoid excessive copying. The monolithic approach, on the other hand, constructs an array all at once, without reference to intermediate array values. Although Haskell has an incremental array update operator, the main thrust of the array facility is monolithic. Arrays are not part of the Standard Prelude---the standard library contains the array operators. Any module using arrays must import the @Array@ module. \subsection{Index types} The @Ix@ library defines a type class of array indices: \bprog @ class (Ord a) => Ix a where range :: (a,a) -> [a] index :: (a,a) a -> Int inRange :: (a,a) -> a -> Bool @ \eprog Instance declarations are provided for @Int@, @Integer@, @Char@, @Bool@, and tuples of @Ix@ types up to length 5; in addition, instances may be automatically derived for enumerated and tuple types. We regard the primitive types as vector indices, and tuples as indices of multidimensional rectangular arrays. Note that the first argument of each of the operations of class @Ix@ is a pair of indices; these are typically the {\em bounds} (first and last indices) of an array. For example, the bounds of a 10-element, zero-origin vector with @Int@ indices would be @(0,9)@, while a 100 by 100 1-origin matrix might have the bounds @((1,1),(100,100))@. (In many other languages, such bounds would be written in a form like @1:100, 1:100@, but the present form fits the type system better, since each bound is of the same type as a general index.) The @range@ operation takes a bounds pair and produces the list of indices lying between those bounds, in index order. For example, \[ @range (0,4)@\ \ \ \ \red\ \ \ \ @[0,1,2,3,4]@ \] \[ @range ((0,0),(1,2))@\ \ \ \ \red\ \ \ \ % @[(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]@ \] The @inRange@ predicate determines whether an index lies between a given pair of bounds. (For a tuple type, this test is performed component-wise.) Finally, the @index@ operation allows a particular element of an array to be addressed: given a bounds pair and an in-range index, the operation yields the zero-origin ordinal of the index within the range; for example: \[ @index (1,9) 2@\ \ \ \ \red\ \ \ \ @1@ \] \[ @index ((0,0),(1,2)) (1,1)@\ \ \ \ \red\ \ \ \ @4@ \] \subsection{Array Creation} Haskell's monolithic array creation function forms an array from a pair of bounds and a list of index-value pairs (an {\em association list}): \bprog @ array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b @ \eprog Here, for example, is a definition of an array of the squares of numbers from 1 to 100: \bprog @ squares = array (1,100) [(i, i*i) | i <- [1..100]] @ \eprog This array expression is typical in using a list comprehension for the association list; in fact, this usage results in array expressions much like the {\em array comprehensions} of the language Id~\cite{id-manual}. Array subscripting is performed with the infix operator @!@, and the bounds of an array can be extracted with the function @bounds@: \[ @squares!7@\ \ \ \ \red\ \ \ \ @49@ \] \[ @bounds squares@\ \ \ \ \red\ \ \ \ @(1,100)@ \] We might generalize this example by parameterizing the bounds and the function to be applied to each index: \bprog @ mkArray :: (Ix a) => (a -> b) -> (a,a) -> Array a b mkArray f bnds = array bnds [(i, f i) | i <- range bnds] @ \eprog Thus, we could define @squares@ as @mkArray (\i -> i * i) (1,100)@. Many arrays are defined recursively; that is, with the values of some elements depending on the values of others. Here, for example, we have a function returning an array of Fibonacci numbers: \bprog @ fibs :: Int -> Array Int Int fibs n = a where a = array (0,n) ([(0, 1), (1, 1)] ++ [(i, a!(i-2) + a!(i-1)) | i <- [2..n]]) @ \eprog Another example of such a recurrence is the "n" by "n" {\em wavefront} matrix, in which elements of the first row and first column all have the value "1" and other elements are sums of their neighbors to the west, northwest, and north: \bprog @ wavefront :: Int -> Array (Int,Int) Int wavefront n = a where a = array ((1,1),(n,n)) ([((1,j), 1) | j <- [1..n]] ++ [((i,1), 1) | i <- [2..n]] ++ [((i,j), a!(i,j-1) + a!(i-1,j-1) + a!(i-1,j)) | i <- [2..n], j <- [2..n]]) @ \eprog The wavefront matrix is so called because in a parallel implementation, the recurrence dictates that the computation can begin with the first row and column in parallel and proceed as a wedge-shaped wave, traveling from northwest to southeast. It is important to note, however, that no order of computation is specified by the association list. In each of our examples so far, we have given a unique association for each index of the array and only for the indices within the bounds of the array, and indeed, we must do this in general for an array be fully defined. An association with an out-of-bounds index results in an error; if an index is missing or appears more than once, however, there is no immediate error, but the value of the array at that index is then undefined, so that subscripting the array with such an index yields an error. \subsection{Accumulation} We can relax the restriction that an index appear at most once in the association list by specifying how to combine multiple values associated with a single index; the result is called an {\em accumulated array}: \bprog @ accumArray :: (Ix a) -> (b -> c -> b) -> b -> (a,a) -> [Assoc a c] -> Array a b @ \eprog The first argument of @accumArray@ is the {\em accumulating function}, the second is an initial value (the same for each element of the array), and the remaining arguments are bounds and an association list, as with the @array@ function. Typically, the accumulating function is @(+)@, and the initial value, zero; for example, this function takes a pair of bounds and a list of values (of an index type) and yields a histogram; that is, a table of the number of occurrences of each value within the bounds: \bprog @ hist :: (Ix a, Integral b) => (a,a) -> [a] -> Array a b hist bnds is = accumArray (+) 0 bnds [(i, 1) | i <- is, inRange bnds i] @ \eprog Suppose we have a collection of measurements on the interval "[a,b)", and we want to divide the interval into decades and count the number of measurements within each: \bprog @ decades :: (RealFrac a) => a -> a -> [a] -> Array Int Int decades a b = hist (0,9) . map decade where decade x = floor ((x - a) * s) s = 10 / (b - a) @ \eprog \subsection{Incremental updates} In addition to the monolithic array creation functions, Haskell also has an incremental array update function, written as the infix operator @//@; the simplest case, an array @a@ with element @i@ updated to @v@, is written @a // [(i, v)]@. The reason for the square brackets is that the left argument of @(//)@ is an association list, usually containing a proper subset of the indices of the array: \bprog @ (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b @ \eprog As with the @array@ function, the indices in the association list must be unique for the values to be defined. For example, here is a function to interchange two rows of a matrix: \bprog @ swapRows :: (Ix a, Ix b, Enum b) => a -> a -> Array (a,b) c -> Array (a,b) c swapRows i i' a = a // ([((i ,j), a!(i',j)) | j <- [jLo..jHi]] ++ [((i',j), a!(i ,j)) | j <- [jLo..jHi]]) where ((iLo,jLo),(iHi,jHi)) = bounds a @ \eprog The concatenation here of two separate list comprehensions over the same list of @j@ indices is, however, a slight inefficiency; it's like writing two loops where one will do in an imperative language. Never fear, we can perform the equivalent of a loop fusion optimization in Haskell: \bprog @ swapRows i i' a = a // [assoc | j <- [jLo..jHi], assoc <- [((i ,j), a!(i',j)), ((i',j), a!(i, j))] ] where ((iLo,jLo),(iHi,jHi)) = bounds a @ \eprog \subsection{An example: Matrix Multiplication} We complete our introduction to Haskell arrays with the familiar example of matrix multiplication, taking advantage of overloading to define a fairly general function. Since only multiplication and addition on the element type of the matrices is involved, we get a function that multiplies matrices of any numeric type unless we try hard not to. Additionally, if we are careful to apply only @(!)@ and the operations of @Ix@ to indices, we get genericity over index types, and in fact, the four row and column index types need not all be the same. For simplicity, however, we require that the left column indices and right row indices be of the same type, and moreover, that the bounds be equal: \bprog @ matMult :: (Ix a, Ix b, Ix c, Num d) => Array (a,b) d -> Array (b,c) d -> Array (a,c) d matMult x y = array resultBounds [((i,j), sum [x!(i,k) * y!(k,j) | k <- range (lj,uj)]) | i <- range (li,ui), j <- range (lj',uj') ] where ((li,lj),(ui,uj)) = bounds x ((li',lj'),(ui',uj')) = bounds y resultBounds | (lj,uj)==(li',ui') = ((li,lj'),(ui,uj')) | otherwise = error "matMult: incompatible bounds" @ \eprog As an aside, we can also define @matMult@ using @accumArray@, resulting in a presentation that more closely resembles the usual formulation in an imperative language: \bprog @ matMult x y = accumArray (+) 0 resultBounds [((i,j), x!(i,k) * y!(k,j)) | i <- range (li,ui), j <- range (lj',uj') k <- range (lj,uj) ] where ((li,lj),(ui,uj)) = bounds x ((li',lj'),(ui',uj')) = bounds y resultBounds | (lj,uj)==(li',ui') = ((li,lj'),(ui,uj')) | otherwise = error "matMult: incompatible bounds" @ \eprog We can generalize further by making the function higher-order, simply replacing @sum@ and @(*)@ by functional parameters: \bprog @ genMatMult :: (Ix a, Ix b, Ix c) => ([f] -> g) -> (d -> e -> f) -> Array (a,b) d -> Array (b,c) e -> Array (a,c) g genMatMult sum' star x y = array resultBounds [((i,j), sum' [x!(i,k) `star` y!(k,j) | k <- range (lj,uj)]) | i <- range (li,ui), j <- range (lj',uj') ] where ((li,lj),(ui,uj)) = bounds x ((li',lj'),(ui',uj')) = bounds y resultBounds | (lj,uj)==(li',ui') = ((li,lj'),(ui,uj')) | otherwise = error "matMult: incompatible bounds" @ \eprog APL fans will recognize the usefulness of functions like the following: \bprog @ genMatMult maximum (-) genMatMult and (==) @ \eprog With the first of these, the arguments are numeric matrices, and the "(i,j)"-th element of the result is the maximum difference between corresponding elements of the "i"-th row and "j"-th column of the inputs. In the second case, the arguments are matrices of any equality type, and the result is a Boolean matrix in which element "(i,j)" is @True@ if and only if the "i"-th row of the first argument and "j"-th column of the second are equal as vectors. Notice that the element types of @genMatMult@ need not be the same, but merely appropriate for the function parameter @star@. We could generalize still further by dropping the requirement that the first column index and second row index types be the same; clearly, two matrices could be considered conformable as long as the lengths of the columns of the first and the rows of the second are equal. The reader may wish to derive this still more general version. ({\bf Hint:} Use the @index@ operation to determine the lengths.) %**~footer haskell-98-tutorial-sources/classes.verb0100644000106400000620000004121107121452152016715 0ustar jcpftp%**A Gentle Introduction to Haskell: Classes %**~header \section{Type Classes and Overloading} \label{tut-type-classes} There is one final feature of Haskell's type system that sets it apart from other programming languages. The kind of polymorphism that we have talked about so far is commonly called {\em parametric} polymorphism. There is another kind called {\em ad hoc} polymorphism, better known as {\em overloading}. Here are some examples of {\em ad hoc} polymorphism: \begin{itemize} \item The literals @1@, @2@, etc. are often used to represent both fixed and arbitrary precision integers. \item Numeric operators such as @+@ are often defined to work on many different kinds of numbers. \item The equality operator (@==@ in Haskell) usually works on numbers and many other (but not all) types. \end{itemize} Note that these overloaded behaviors are different for each type (in fact the behavior is sometimes undefined, or error), whereas in parametric polymorphism the type truly does not matter (@fringe@, for example, really doesn't care what kind of elements are found in the leaves of a tree). In Haskell, {\em type classes} provide a structured way to control {\em ad hoc} polymorphism, or overloading. Let's start with a simple, but important, example: equality. There are many types for which we would like equality defined, but some for which we would not. For example, comparing the equality of functions is generally considered computationally intractable, whereas we often want to compare two lists for equality.\footnote{The kind of equality we are referring to here is ``value equality,'' and opposed to the ``pointer equality'' found, for example, with Java's @==@. Pointer equality is not referentially transparent, and thus does not sit well in a purely functional language.} To highlight the issue, consider this definition of the function @elem@ which tests for membership in a list: \bprog @ x `elem` [] = False x `elem` (y:ys) = x==y || (x `elem` ys) @ \eprog \syn{For the stylistic reason we discussed in Section \ref{tut-lambda}, we have chosen to define @elem@ in infix form. @==@ and @||@ are the infix operators for equality and logical or, respectively.} \noindent Intuitively speaking, the type of @elem@ ``ought'' to be: @a->[a]->Bool@. But this would imply that @==@ has type @a->a->Bool@, even though we just said that we don't expect @==@ to be defined for all types. Furthermore, as we have noted earlier, even if @==@ were defined on all types, comparing two lists for equality is very different from comparing two integers. In this sense, we expect @==@ to be {\em overloaded} to carry on these various tasks. {\em Type classes} conveniently solve both of these problems. They allow us to declare which types are {\em instances} of which class, and to provide definitions of the overloaded {\em operations} associated with a class. For example, let's define a type class containing an equality operator: \bprog @ class Eq a where (==) :: a -> a -> Bool @ \eprog Here @Eq@ is the name of the class being defined, and @==@ is the single operation in the class. This declaration may be read ``a type @a@ is an instance of the class @Eq@ if there is an (overloaded) operation @==@, of the appropriate type, defined on it.'' (Note that @==@ is only defined on pairs of objects of the same type.) The constraint that a type @a@ must be an instance of the class @Eq@ is written @Eq a@. Thus @Eq a@ is not a type expression, but rather it expresses a constraint on a type, and is called a {\em context}. Contexts are placed at the front of type expressions. For example, the effect of the above class declaration is to assign the following type to @==@: \bprog @ (==) :: (Eq a) => a -> a -> Bool @ \eprog This should be read, ``For every type @a@ that is an instance of the class @Eq@, @==@ has type @a->a->Bool@''. This is the type that would be used for @==@ in the @elem@ example, and indeed the constraint imposed by the context propagates to the principal type for @elem@: \bprog @ elem :: (Eq a) => a -> [a] -> Bool @ \eprog This is read, ``For every type @a@ that is an instance of the class @Eq@, @elem@ has type @a->[a]->Bool@''. This is just what we want---it expresses the fact that @elem@ is not defined on all types, just those for which we know how to compare elements for equality. So far so good. But how do we specify which types are instances of the class @Eq@, and the actual behavior of @==@ on each of those types? This is done with an {\em instance declaration}. For example: \bprog @ instance Eq Integer where x == y = x `integerEq` y @ \eprog The definition of @==@ is called a {\em method}. The function @integerEq@ happens to be the primitive function that compares integers for equality, but in general any valid expression is allowed on the right-hand side, just as for any other function definition. The overall declaration is essentially saying: ``The type @Integer@ is an instance of the class @Eq@, and here is the definition of the method corresponding to the operation @==@.'' Given this declaration, we can now compare fixed precision integers for equality using @==@. Similarly: \bprog @ instance Eq Float where x == y = x `floatEq` y @ \eprog allows us to compare floating point numbers using @==@. Recursive types such as @Tree@ defined earlier can also be handled: \bprog @ instance (Eq a) => Eq (Tree a) where Leaf a == Leaf b = a == b (Branch l1 r1) == (Branch l2 r2) = (l1==l2) && (r1==r2) _ == _ = False @ \eprog Note the context @Eq a@ in the first line---this is necessary because the elements in the leaves (of type @a@) are compared for equality in the second line. The additional constraint is essentially saying that we can compare trees of @a@'s for equality as long as we know how to compare @a@'s for equality. If the context were omitted from the instance declaration, a static type error would result. The Haskell Report, especially the Prelude, contains a wealth of useful examples of type classes. Indeed, a class @Eq@ is defined that is slightly larger than the one defined earlier: \bprog @ class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) @ \eprog This is an example of a class with two operations, one for equality, the other for inequality. It also demonstrates the use of a {\em default method}, in this case for the inequality operation @/=@. If a method for a particular operation is omitted in an instance declaration, then the default one defined in the class declaration, if it exists, is used instead. For example, the three instances of @Eq@ defined earlier will work perfectly well with the above class declaration, yielding just the right definition of inequality that we want: the logical negation of equality. Haskell also supports a notion of {\em class extension}. For example, we may wish to define a class @Ord@ which {\em inherits} all of the operations in @Eq@, but in addition has a set of comparison operations and minimum and maximum functions: \bprog @ class (Eq a) => Ord a where (<), (<=), (>=), (>) :: a -> a -> Bool max, min :: a -> a -> a @ \eprog Note the context in the @class@ declaration. We say that @Eq@ is a {\em superclass} of @Ord@ (conversely, @Ord@ is a {\em subclass} of @Eq@), and any type which is an instance of @Ord@ must also be an instance of @Eq@. (In the next Section we give a fuller definition of @Ord@ taken from the Prelude.) One benefit of such class inclusions is shorter contexts: a type expression for a function that uses operations from both the @Eq@ and @Ord@ classes can use the context @(Ord a)@, rather than @(Eq a, Ord a)@, since @Ord@ ``implies'' @Eq@. More importantly, methods for subclass operations can assume the existence of methods for superclass operations. For example, the @Ord@ declaration in the Standard Prelude contains this default method for @(<)@: \bprog @ x < y = x <= y && x /= y @ \eprog As an example of the use of @Ord@, the principal typing of @quicksort@ defined in Section \ref{tut-list-comps} is: \bprog @ quicksort :: (Ord a) => [a] -> [a] @ \eprog In other words, @quicksort@ only operates on lists of values of ordered types. This typing for @quicksort@ arises because of the use of the comparison operators @<@ and @>=@ in its definition. Haskell also permits {\em multiple inheritance}, since classes may have more than one superclass. For example, the declaration \bprog @ class (Eq a, Show a) => C a where ... @ \eprog creates a class @C@ which inherits operations from both @Eq@ and @Show@. Class methods are treated as top level declarations in Haskell. They share the same namespace as ordinary variables; a name cannot be used to denote both a class method and a variable or methods in different classes. Contexts are also allowed in @data@ declarations; see \see{datatype-decls}. Class methods may have additional class constraints on any type variable except the one defining the current class. For example, in this class: \bprog @ class C a where m :: Show b => a -> b @ \eprog the method @m@ requires that type @b@ is in class @Show@. However, the method @m@ could not place any additional class constraints on type @a@. These would instead have to be part of the context in the class declaration. So far, we have been using ``first-order'' types. For example, the type constructor @Tree@ has so far always been paired with an argument, as in @Tree Integer@ (a tree containing @Integer@ values) or @Tree a@ (representing the family of trees containing @a@ values). But @Tree@ by itself is a type constructor, and as such takes a type as an argument and returns a type as a result. There are no values in Haskell that have this type, but such ``higher-order'' types can be used in @class@ declarations. To begin, consider the following @Functor@ class (taken from the Prelude): \bprog @ class Functor f where fmap :: (a -> b) -> f a -> f b @ \eprog The @fmap@ function generalizes the @map@ function used previously. Note that the type variable @f@ is applied to other types in @f a@ and @f b@. Thus we would expect it to be bound to a type such as @Tree@ which can be applied to an argument. An instance of @Functor@ for type @Tree@ would be: \bprog @ instance Functor Tree where fmap f (Leaf x) = Leaf (f x) fmap f (Branch t1 t2) = Branch (fmap f t1) (fmap f t2) @ \eprog This instance declaration declares that @Tree@, rather than @Tree a@, is an instance of @Functor@. This capability is quite useful, and here demonstrates the ability to describe generic ``container'' types, allowing functions such as @fmap@ to work uniformly over arbitrary trees, lists, and other data types. \syn{Type applications are written in the same manner as function applications. The type @T a b@ is parsed as @(T a) b@. Types such as tuples which use special syntax can be written in an alternative style which allows currying. For functions, @(->)@ is a type constructor; the types @f -> g@ and @(->) f g@ are the same. Similarly, the types @[a]@ and @[] a@ are the same. For tuples, the type constructors (as well as the data constructors) are @(,)@, @(,,)@, and so on.} As we know, the type system detects typing errors in expressions. But what about errors due to malformed type expressions? The expression @(+) 1 2 3@ results in a type error since @(+)@ takes only two arguments. Similarly, the type @Tree Int Int@ should produce some sort of an error since the @Tree@ type takes only a single argument. So, how does Haskell detect malformed type expressions? The answer is a second type system which ensures the correctness of types! Each type has an associated "kind" which ensures that the type is used correctly. Type expressions are classified into different {\em kinds} which take one of two possible forms: \begin{itemize} \item The symbol $\ast$ represents the kind of type associated with concrete data objects. That is, if the value "v" has type "t", the kind of "v" must be $\ast$. \item If $\kappa_1$ and $\kappa_2$ are kinds, then $\kappa_1\rightarrow\kappa_2$ is the kind of types that take a type of kind $\kappa_1$ and return a type of kind $\kappa_2$. \end{itemize} The type constructor @Tree@ has the kind $\ast\rightarrow\ast$; the type @Tree Int@ has the kind $\ast$. Members of the @Functor@ class must all have the kind $\ast\rightarrow\ast$; a kinding error would result from an declaration such as \bprog @ instance Functor Integer where ... @ \eprog since @Integer@ has the kind $\ast$. Kinds do not appear directly in Haskell programs. The compiler infers kinds before doing type checking without any need for `kind declarations'. Kinds stay in the background of a Haskell program except when an erroneous type signature leads to a kind error. Kinds are simple enough that compilers should be able to provide descriptive error messages when kind conflicts occur. See \see{type-syntax} and \see{kindinference} for more information about kinds. \paragraph*{A Different Perspective.} Before going on to further examples of the use of type classes, it is worth pointing out two other views of Haskell's type classes. The first is by analogy with object-oriented programming (OOP). In the following general statement about OOP, simply substituting {\em type class} for {\em class}, and {\em type} for {\em object}, yields a valid summary of Haskell's type class mechanism: ``{\em Classes} capture common sets of operations. A particular {\em object} may be an instance of a {\em class}, and will have a method corresponding to each operation. {\em Classes} may be arranged hierarchically, forming notions of super{\em classes} and sub{\em classes}, and permitting inheritance of operations/methods. A default method may also be associated with an operation.'' In contrast to OOP, it should be clear that types are not objects, and in particular there is no notion of an object's or type's internal mutable state. An advantage over some OOP languages is that methods in Haskell are completely type-safe: any attempt to apply a method to a value whose type is not in the required class will be detected at compile time instead of at runtime. In other words, methods are not ``looked up'' at runtime but are simply passed as higher-order functions. A different perspective can be gotten by considering the relationship between parametric and {\em ad hoc} polymorphism. We have shown how parametric polymorphism is useful in defining families of types by universally quantifying over all types. Sometimes, however, that universal quantification is too broad---we wish to quantify over some smaller set of types, such as those types whose elements can be compared for equality. Type classes can be seen as providing a structured way to do just this. Indeed, we can think of parametric polymorphism as a kind of overloading too! It's just that the overloading occurs implicitly over all types instead of a constrained set of types (i.e.~a type class). \paragraph*{Comparison to Other Languages.} The classes used by Haskell are similar to those used in other object-oriented languages such as C++ and Java. However, there are some significant differences: \begin{itemize} \item Haskell separates the definition of a type from the definition of the methods associated with that type. A class in C++ or Java usually defines both a data structure (the member variables) and the functions associated with the structure (the methods). In Haskell, these definitions are separated. \item The class methods defined by a Haskell class correspond to virtual functions in a C++ class. Each instance of a class provides its own definition for each method; class defaults correspond to default definitions for a virtual function in the base class. \item Haskell classes are roughly similar to a Java interface. Like an interface declaration, a Haskell class declaration defines a protocol for using an object rather than defining an object itself. \item Haskell does not support the C++ overloading style in which functions with different types share a common name. \item The type of a Haskell object cannot be implicitly coerced; there is no universal base class such as @Object@ which values can be projected into or out of. \item C++ and Java attach identifying information (such as a VTable) to the runtime representation of an object. In Haskell, such information is attached logically instead of physically to values, through the type system. \item There is no access control (such as public or private class constituents) built into the Haskell class system. Instead, the module system must be used to hide or reveal components of a class. \end{itemize} %**~footer haskell-98-tutorial-sources/end.verb0100644000106400000620000000156606774446522016060 0ustar jcpftp%**A Gentle Introduction to Haskell: The Next Stage %**~eheader \section{The Next Stage} A large collection of Haskell resources is available on the web at @haskell.org@. Here you will find compilers, demos, papers, and much valuable information about Haskell and functional programming. Haskell compilers or interpreters run on almost all hardware and operating systems. The Hugs system is both small and portable -- it is an excellent vehicle for learning Haskell. \section{Acknowledgements} Thanks to Patricia Fasel and Mark Mundt at Los Alamos, and Nick Carriero, Charles Consel, Amir Kishon, Sandra Loosemore, Martin Odersky, and David Rochberg at Yale University for their quick readings of earlier drafts of this manuscript. Special thanks to Erik Meijer for his extensive comments on the new material added for version 1.4 of this tutorial. %**~efooter haskell-98-tutorial-sources/functions.verb0100644000106400000620000003321407065436745017315 0ustar jcpftp%**A Gentle Introduction to Haskell: Functions %**~header %%% \section{Functions} \label{tut-functions} Since Haskell is a functional language, one would expect functions to play a major role, and indeed they do. In this section, we look at several aspects of functions in Haskell. First, consider this definition of a function which adds its two arguments: \bprog @ add :: Integer -> Integer -> Integer add x y = x + y @ \eprog This is an example of a {\em curried} function.\footnote{The name {\em curry} derives from the person who popularized the idea: Haskell Curry. To get the effect of an {\em uncurried} function, we could use a {\em tuple}, as in: \bprog @ add (x,y) = x + y @ \eprog But then we see that this version of @add@ is really just a function of one argument!} An application of @add@ has the form @add @$e_1\ e_2$, and is equivalent to @(add @$e_1$@) @$e_2$, since function application associates to the {\em left}. In other words, applying @add@ to one argument yields a new function which is then applied to the second argument. This is consistent with the type of @add@, @Integer->Integer->Integer@, which is equivalent to @Integer->(Integer->Integer)@; i.e.~@->@ associates to the {\em right}. Indeed, using @add@, we can define @inc@ in a different way from earlier: \bprog @ inc = add 1 @ \eprog This is an example of the {\em partial application} of a curried function, and is one way that a function can be returned as a value. Let's consider a case in which it's useful to pass a function as an argument. The well-known @map@ function is a perfect example: \bprog @ map :: (a->b) -> [a] -> [b] map f [] = [] map f (x:xs) = f x : map f xs @ \eprog \syn{Function application has higher precedence than any infix operator, and thus the right-hand side of the second equation parses as @(f x) : (map f xs)@.}\ \ \ The @map@ function is polymorphic and its type indicates clearly that its first argument is a function; note also that the two @a@'s must be instantiated with the same type (likewise for the @b@'s). As an example of the use of @map@, we can increment the elements in a list: \[ @map (add 1) [1,2,3]@\ \ \ \ \red\ \ \ \ @[2,3,4]@ \] These examples demonstrate the first-class nature of functions, which when used in this way are usually called {\em higher-order} functions. \subsection{Lambda Abstractions} \label{tut-lambda} Instead of using equations to define functions, we can also define them ``anonymously'' via a {\em lambda abstraction}. For example, a function equivalent to @inc@ could be written as @\x -> x+1@. Similarly, the function @add@ is equivalent to @\x -> \y -> x+y@. Nested lambda abstractions such as this may be written using the equivalent shorthand notation @\x y -> x+y@. In fact, the equations: \bprog @ inc x = x+1 add x y = x+y @ \eprog are really shorthand for: \bprog @ inc = \x -> x+1 add = \x y -> x+y @ \eprog We will have more to say about such equivalences later. In general, given that @x@ has type $t_1$ and @exp@ has type $t_2$, then @\x->exp@ has type $t_1$@->@$t_2$. \subsection{Infix Operators} \label{tut-infix-ops} Infix operators are really just functions, and can also be defined using equations. For example, here is a definition of a list concatenation operator: \bprog @ (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs++ys) @ \eprog \syn{Lexically, infix operators consist entirely of ``symbols,'' as opposed to normal identifiers which are alphanumeric (\see{ids}). Haskell has no prefix operators, with the exception of minus (@-@), which is both infix and prefix.} As another example, an important infix operator on functions is that for {\em function composition}: \bprog @ (.) :: (b->c) -> (a->b) -> (a->c) f . g = \ x -> f (g x) @ \eprog \subsubsection{Sections} \label{tut-sections} Since infix operators are really just functions, it makes sense to be able to partially apply them as well. In Haskell the partial application of an infix operator is called a {\em section}. For example: \[\ba{ccc} @(x+)@\ \ \ \ &\equiv&\ \ \ \ @\y -> x+y@ \\ @(+y)@\ \ \ \ &\equiv&\ \ \ \ @\x -> x+y@ \\ @(+)@ \ \ \ \ &\equiv&\ \ \ \ @\x y -> x+y@ \ea\] \syn{The parentheses are mandatory.} The last form of section given above essentially coerces an infix operator into an equivalent functional value, and is handy when passing an infix operator as an argument to a function, as in @map (+) [1,2,3]@ (the reader should verify that this returns a list of functions!). It is also necessary when giving a function type signature, as in the examples of @(++)@ and @(.)@ given earlier. We can now see that @add@ defined earlier is just @(+)@, and @inc@ is just @(+1)@! Indeed, these definitions would do just fine: \bprog @ inc = (+ 1) add = (+) @ \eprog We can coerce an infix operator into a functional value, but can we go the other way? Yes---we simply enclose an identifier bound to a functional value in backquotes. For example, @x `add` y@ is the same as @add x y@.\footnote{Note carefully that @add@ is enclosed in {\em backquotes}, not {\em apostrophes} as used in the syntax of characters; i.e. @'f'@ is a character, whereas @`f`@ is an infix operator. Fortunately, most ASCII terminals distinguish these much better than the font used in this manuscript.} Some functions read better this way. An example is the predefined list membership predicate @elem@; the expression @x `elem` xs@ can be read intuitively as ``@x@ is an element of @xs@.'' \syn{There are some special rules regarding sections involving the prefix/infix operator @-@; see (\see{sections},\see{operators}).} At this point, the reader may be confused at having so many ways to define a function! The decision to provide these mechanisms partly reflects historical conventions, and partly reflects the desire for consistency (for example, in the treatment of infix vs. regular functions). % That's all right---the designers of Haskell are too. \subsubsection{Fixity Declarations} A {\em fixity declaration} can be given for any infix operator or constructor (including those made from ordinary identifiers, such as @`elem`@). %\footnote{Fixity declarations must only appear at the very %beginning of a Haskell {\em module}, as will be described in Section %\ref{tut-modules}.} This declaration specifies a precedence level from 0 to 9 (with 9 being the strongest; normal application is assumed to have a precedence level of 10), and left-, right-, or non-associativity. For example, the fixity declarations for @++@ and @.@ are: \bprog @ infixr 5 ++ infixr 9 . @ \eprog Both of these specify right-associativity, the first with a precedence level of 5, the other 9. Left associativity is specified via @infixl@, and non-associativity by @infix@. Also, the fixity of more than one operator may be specified with the same fixity declaration. If no fixity declaration is given for a particular operator, it defaults to @infixl 9@. (See \see{fixity} for a detailed definition of the associativity rules.) \subsection{Functions are Non-strict} \label{tut-non-strict} Suppose @bot@ is defined by: \bprog @ bot = bot @ \eprog In other words, @bot@ is a non-terminating expression. Abstractly, we denote the {\em value} of a non-terminating expression as $\bot$ (read ``bottom''). Expressions that result in some kind of a run-time error, such as @1/0@, also have this value. Such an error is not recoverable: programs will not continue past these errors. Errors encountered by the I/O system, such as an end-of-file error, are recoverable and are handled in a different manner. (Such an I/O error is really not an error at all but rather an exception. Much more will be said about exceptions in Section \ref{tut-io}.) A function @f@ is said to be {\em strict} if, when applied to a nonterminating expression, it also fails to terminate. In other words, @f@ is strict iff the value of @f bot@ is $\bot$. For most programming languages, {\em all} functions are strict. But this is not so in Haskell. As a simple example, consider @const1@, the constant 1 function, defined by: \bprog @ const1 x = 1 @ \eprog The value of @const1 bot@ in Haskell is @1@. Operationally speaking, since @const1@ does not ``need'' the value of its argument, it never attempts to evaluate it, and thus never gets caught in a nonterminating computation. For this reason, non-strict functions are also called ``lazy functions'', and are said to evaluate their arguments ``lazily'', or ``by need''. Since error and nonterminating values are semantically the same in Haskell, the above argument also holds for errors. For example, @const1 (1/0)@ also evaluates properly to @1@. Non-strict functions are extremely useful in a variety of contexts. The main advantage is that they free the programmer from many concerns about evaluation order. Computationally expensive values may be passed as arguments to functions without fear of them being computed if they are not needed. An important example of this is a possibly {\em infinite} data structure. Another way of explaining non-strict functions is that Haskell computes using "definitions" rather than the "assignments" found in traditional languages. Read a declaration such as \bprog @ v = 1/0 @ \eprog as `define @v@ as @1/0@' instead of `compute @1/0@ and store the result in @v@'. Only if the value (definition) of @v@ is needed will the division by zero error occur. By itself, this declaration does not imply any computation. Programming using assignments requires careful attention to the ordering of the assignments: the meaning of the program depends on the order in which the assignments are executed. Definitions, in contrast, are much simpler: they can be presented in any order without affecting the meaning of the program. \subsection{``Infinite'' Data Structures} \label{tut-infinite} One advantage of the non-strict nature of Haskell is that data constructors are non-strict, too. This should not be surprising, since constructors are really just a special kind of function (the distinguishing feature being that they can be used in pattern matching). For example, the constructor for lists, @(:)@, is non-strict. Non-strict constructors permit the definition of (conceptually) {\em infinite} data structures. Here is an infinite list of ones: \bprog @ ones = 1 : ones @ \eprog Perhaps more interesting is the function @numsFrom@: \bprog @ numsFrom n = n : numsFrom (n+1) @ \eprog Thus @numsFrom n@ is the infinite list of successive integers beginning with @n@. From it we can construct an infinite list of squares: \bprog @ squares = map (^2) (numsfrom 0) @ \eprog (Note the use of a section; @^@ is the infix exponentiation operator.) Of course, eventually we expect to extract some finite portion of the list for actual computation, and there are lots of predefined functions in Haskell that do this sort of thing: @take@, @takeWhile@, @filter@, and others. The definition of Haskell includes a large set of built-in functions and types---this is called the ``Standard Prelude''. The complete Standard Prelude is included in Appendix A of the Haskell report; see the portion named @PreludeList@ for many useful functions involving lists. For example, @take@ removes the first @n@ elements from a list: \[ @take 5 squares@\ \ \ \ \red\ \ \ \ @[0,1,4,9,16]@ \] The definition of @ones@ above is an example of a {\em circular list}. In most circumstances laziness has an important impact on efficiency, since an implementation can be expected to implement the list as a true circular structure, thus saving space. For another example of the use of circularity, the Fibonacci sequence can be computed efficiently as the following infinite sequence: \bprog @ fib = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ] @ \eprog where @zip@ is a Standard Prelude function that returns the pairwise interleaving of its two list arguments: \bprog @ zip (x:xs) (y:ys) = (x,y) : zip xs ys zip xs ys = [] @ \eprog Note how @fib@, an infinite list, is defined in terms of itself, as if it were ``chasing its tail.'' Indeed, we can draw a picture of this computation as shown in Figure \ref{tut-fib-fig}. %**
Fib Example %**

Figure 1

For another application of infinite lists, see Section \ref{tut-lazy-patterns}. %*ignore \begin{figure} \begin{center} \mbox{ {\epsfxsize=2.5in \epsfbox{fig1.eps}}} \end{center} \caption{Circular Fibonacci Sequence} \label{tut-fib-fig} \end{figure} %*endignore \subsection{The Error Function} Haskell has a built-in function called @error@ whose type is @String->a@. This is a somewhat odd function: From its type it looks as if it is returning a value of a polymorphic type about which it knows nothing, since it never receives a value of that type as an argument! In fact, there {\em is} one value ``shared'' by all types: $\bot$. Indeed, semantically that is exactly what value is always returned by @error@ (recall that all errors have value $\bot$). However, we can expect that a reasonable implementation will print the string argument to @error@ for diagnostic purposes. Thus this function is useful when we wish to terminate a program when something has ``gone wrong.'' For example, the actual definition of @head@ taken from the Standard Prelude is: \bprog @ head (x:xs) = x head [] = error "head{PreludeList}: head []" @ \eprog %**~footer haskell-98-tutorial-sources/goodies.verb0100644000106400000620000005460707065431554016740 0ustar jcpftp%**A Gentle Introduction to Haskell: Values and Types %**~header \section{Values, Types, and Other Goodies} \label{tut-values-etc} Because Haskell is a purely functional language, all computations are done via the evaluation of {\em expressions} (syntactic terms) to yield {\em values} (abstract entities that we regard as answers). Every value has an associated {\em type}. (Intuitively, we can think of types as sets of values.) Examples of expressions include atomic values such as the integer @5@, the character @'a'@, and the function @\x -> x+1@, as well as structured values such as the list @[1,2,3]@ and the pair @('b',4)@. Just as expressions denote values, type expressions are syntactic terms that denote type values (or just {\em types}). Examples of type expressions include the atomic types @Integer@ (infinite-precision integers), @Char@ (characters), @Integer->Integer@ (functions mapping @Integer@ to @Integer@), as well as the structured types @[Integer]@ (homogeneous lists of integers) and @(Char,Integer)@ (character, integer pairs). All Haskell values are ``first-class''---they may be passed as arguments to functions, returned as results, placed in data structures, etc. Haskell types, on the other hand, are {\em not} first-class. Types in a sense describe values, and the association of a value with its type is called a {\em typing}. Using the examples of values and types above, we write typings as follows: \bprog @ 5 :: Integer 'a' :: Char inc :: Integer -> Integer [1,2,3] :: [Integer] ('b',4) :: (Char,Integer) @ \eprog The ``@::@'' can be read ``has type.'' Functions in Haskell are normally defined by a series of {\em equations}. For example, the function @inc@ can be defined by the single equation: \bprog @ inc n = n+1 @ \eprog An equation is an example of a {\em declaration}. Another kind of declaration is a {\em type signature declaration} (\see{type-signatures}), with which we can declare an explicit typing for @inc@: \bprog @ inc :: Integer -> Integer @ \eprog We will have much more to say about function definitions in Section \ref{tut-functions}. For pedagogical purposes, when we wish to indicate that an expression $e_1$ evaluates, or ``reduces,'' to another expression or value $e_2$, we will write: \[ e_1\ \ \ \ \red\ \ \ \ e_2 \] For example, note that: \[ @inc (inc 3)@\ \ \ \ \red\ \ \ \ @5@ \] Haskell's static type system defines the formal relationship between types and values (\see{type-semantics}). The static type system ensures that Haskell programs are {\em type safe}; that is, that the programmer has not mismatched types in some way. For example, we cannot generally add together two characters, so the expression @'a'+'b'@ is ill-typed. The main advantage of statically typed languages is well-known: All type errors are detected at compile-time. Not all errors are caught by the type system; an expression such as @1/0@ is typable but its evaluation will result in an error at execution time. Still, the type system finds many program errors at compile time, aids the user in reasoning about programs, and also permits a compiler to generate more efficient code (for example, no run-time type tags or tests are required). The type system also ensures that user-supplied type signatures are correct. In fact, Haskell's type system is powerful enough to allow us to avoid writing any type signatures at all;\footnote{With a few exceptions to be described later.} we say that the type system {\em infers} the correct types for us. Nevertheless, judicious placement of type signatures such as that we gave for @inc@ is a good idea, since type signatures are a very effective form of documentation and help bring programming errors to light. \syn{The reader will note that we have capitalized identifiers that denote specific types, such as @Integer@ and @Char@, but not identifiers that denote values, such as @inc@. This is not just a convention: it is enforced by Haskell's lexical syntax. In fact, the case of the other characters matters, too: @foo@, @fOo@, and @fOO@ are all distinct identifiers.} \subsection{Polymorphic Types} \label{tut-polymorphism} Haskell also incorporates {\em polymorphic} types---types that are universally quantified in some way over all types. Polymorphic type expressions essentially describe families of types. For example, $(\forall$@a@$)$@[a]@ is the family of types consisting of, for every type @a@, the type of lists of @a@. Lists of integers (e.g.~@[1,2,3]@), lists of characters (@['a','b','c']@), even lists of lists of integers, etc., are all members of this family. (Note, however, that @[2,'b']@ is {\em not} a valid example, since there is no single type that contains both @2@ and @'b'@.) \syn{Identifiers such as @a@ above are called {\em type variables}, and are uncapitalized to distinguish them from specific types such as @Int@. Furthermore, since Haskell has only universally quantified types, there is no need to explicitly write out the symbol for universal quantification, and thus we simply write @[a]@ in the example above. In other words, all type variables are implicitly universally quantified.} Lists are a commonly used data structure in functional languages, and are a good vehicle for explaining the principles of polymorphism. The list @[1,2,3]@ in Haskell is actually shorthand for the list @1:(2:(3:[]))@, where @[]@ is the empty list and @:@ is the infix operator that adds its first argument to the front of its second argument (a list).\footnote{@:@ and @[]@ are like Lisp's @cons@ and @nil@, respectively.} Since @:@ is right associative, we can also write this list as @1:2:3:[]@. As an example of a user-defined function that operates on lists, consider the problem of counting the number of elements in a list: \bprog @ length :: [a] -> Integer length [] = 0 length (x:xs) = 1 + length xs @ \eprog This definition is almost self-explanatory. We can read the equations as saying: ``The length of the empty list is 0, and the length of a list whose first element is @x@ and remainder is @xs@ is 1 plus the length of @xs@.'' (Note the naming convention used here; @xs@ is the plural of @x@, and should be read that way.) Although intuitive, this example highlights an important aspect of Haskell that is yet to be explained: {\em pattern matching}. The left-hand sides of the equations contain patterns such as @[]@ and @x:xs@. In a function application these patterns are matched against actual parameters in a fairly intuitive way (@[]@ only matches the empty list, and @x:xs@ will successfully match any list with at least one element, binding @x@ to the first element and @xs@ to the rest of the list). If the match succeeds, the right-hand side is evaluated and returned as the result of the application. If it fails, the next equation is tried, and if all equations fail, an error results. Defining functions by pattern matching is quite common in Haskell, and the user should become familiar with the various kinds of patterns that are allowed; we will return to this issue in Section~\ref{tut-pattern-matching}. The @length@ function is also an example of a polymorphic function. It can be applied to a list containing elements of any type, for example @[Integer]@, @[Char]@, or @[[Integer]]@. \[\ba{lcl} @length [1,2,3]@ &\ \ \ \ \red\ \ \ \ & 3\\ @length ['a','b','c']@&\ \ \ \ \red\ \ \ \ & 3\\ @length [[1],[2],[3]]@ &\ \ \ \ \red\ \ \ \ & 3 \ea\] Here are two other useful polymorphic functions on lists that will be used later. Function @head@ returns the first element of a list, function @tail@ returns all but the first. \bprog @ head :: [a] -> a head (x:xs) = x tail :: [a] -> [a] tail (x:xs) = xs @ \eprog Unlike @length@, these functions are not defined for all possible values of their argument. A runtime error occurs when these functions are applied to an empty list. With polymorphic types, we find that some types are in a sense strictly more general than others in the sense that the set of values they define is larger. For example, the type @[a]@ is more general than @[Char]@. In other words, the latter type can be derived from the former by a suitable substitution for @a@. With regard to this generalization ordering, Haskell's type system possesses two important properties: First, every well-typed expression is guaranteed to have a unique principal type (explained below), and second, the principal type can be inferred automatically (\see{type-semantics}). In comparison to a monomorphically typed language such as C, the reader will find that polymorphism improves expressiveness, and type inference lessens the burden of types on the programmer. An expression's or function's principal type is the least general type that, intuitively, ``contains all instances of the expression''. For example, the principal type of @head@ is @[a]->a@; @[b]->a@, @a->a@, or even @a@ are correct types, but too general, whereas something like @[Integer]->Integer@ is too specific. The existence of unique principal types is the hallmark feature of the {\em Hindley-Milner type system}, which forms the basis of the type systems of Haskell, ML, Miranda,\footnote{``Miranda'' is a trademark of Research Software, Ltd.} and several other (mostly functional) languages. \subsection{User-Defined Types} \label{tut-user-types} We can define our own types in Haskell using a @data@ declaration, which we introduce via a series of examples (\see{datatype-decls}). An important predefined type in Haskell is that of truth values: \bprog @ data Bool = False | True @ \eprog The type being defined here is @Bool@, and it has exactly two values: @True@ and @False@. Type @Bool@ is an example of a (nullary) {\em type constructor}, and @True@ and @False@ are (also nullary) {\em data constructors} (or just {\em constructors}, for short). Similarly, we might wish to define a color type: \bprog @ data Color = Red | Green | Blue | Indigo | Violet @ \eprog Both @Bool@ and @Color@ are examples of enumerated types, since they consist of a finite number of nullary data constructors. Here is an example of a type with just one data constructor: \bprog @ data Point a = Pt a a @ \eprog Because of the single constructor, a type like @Point@ is often called a {\em tuple type}, since it is essentially just a cartesian product (in this case binary) of other types.\footnote{Tuples are somewhat like records in other languages.} In contrast, multi-constructor types, such as @Bool@ and @Color@, are called (disjoint) union or sum types. More importantly, however, @Point@ is an example of a polymorphic type: for any type $t$, it defines the type of cartesian points that use $t$ as the coordinate type. The @Point@ type can now be seen clearly as a unary type constructor, since from the type $t$ it constructs a new type @Point @$t$. (In the same sense, using the list example given earlier, @[]@ is also a type constructor. Given any type $t$ we can ``apply'' @[]@ to yield a new type @[@$t$@]@. The Haskell syntax allows @[] @$t$ to be written as @[@$t$@]@. Similarly, @->@ is a type constructor: given two types $t$ and $u$, $t$@->@$u$ is the type of functions mapping elements of type $t$ to elements of type $u$.) Note that the type of the binary data constructor @Pt@ is @a -> a -> Point a@, and thus the following typings are valid: \bprog @ Pt 2.0 3.0 :: Point Float Pt 'a' 'b' :: Point Char Pt True False :: Point Bool @ \eprog On the other hand, an expression such as @Pt 'a' 1@ is ill-typed because @'a'@ and @1@ are of different types. It is important to distinguish between applying a {\em data constructor} to yield a {\em value}, and applying a {\em type constructor} to yield a {\em type}; the former happens at run-time and is how we compute things in Haskell, whereas the latter happens at compile-time and is part of the type system's process of ensuring type safety. \syn{Type constructors such as @Point@ and data constructors such as @Pt@ are in separate namespaces. This allows the same name to be used for both a type constructor and data constructor, as in the following: \bprog @ data Point a = Point a a @ \eprog While this may seem a little confusing at first, it serves to make the link between a type and its data constructor more obvious.} \subsubsection{Recursive Types} \label{tut-recursive-types} Types can also be recursive, as in the type of binary trees: \bprog @ data Tree a = Leaf a | Branch (Tree a) (Tree a) @ \eprog Here we have defined a polymorphic binary tree type whose elements are either leaf nodes containing a value of type @a@, or internal nodes (``branches'') containing (recursively) two sub-trees. When reading data declarations such as this, remember again that @Tree@ is a type constructor, whereas @Branch@ and @Leaf@ are data constructors. Aside from establishing a connection between these constructors, the above declaration is essentially defining the following types for @Branch@ and @Leaf@: \bprog @ Branch :: Tree a -> Tree a -> Tree a Leaf :: a -> Tree a @ \eprog With this example we have defined a type sufficiently rich to allow defining some interesting (recursive) functions that use it. For example, suppose we wish to define a function @fringe@ that returns a list of all the elements in the leaves of a tree from left to right. It's usually helpful to write down the type of new functions first; in this case we see that the type should be @Tree a -> [a]@. That is, @fringe@ is a polymorphic function that, for any type @a@, maps trees of @a@ into lists of @a@. A suitable definition follows: \bprog @ fringe :: Tree a -> [a] fringe (Leaf x) = [x] fringe (Branch left right) = fringe left ++ fringe right @ \eprog Here @++@ is the infix operator that concatenates two lists (its full definition will be given in Section \ref{tut-monadic-classes}). As with the @length@ example given earlier, the @fringe@ function is defined using pattern matching, except that here we see patterns involving user-defined constructors: @Leaf@ and @Branch@. \syn{Note that the formal parameters are easily identified as the ones beginning with lower-case letters.} \subsection{Type Synonyms} \label{tut-type-synonyms} For convenience, Haskell provides a way to define {\em type synonyms}; i.e.~names for commonly used types. Type synonyms are created using a @type@ declaration (\see{type-synonym-decls}). Here are several examples: \bprog @ type String = [Char] type Person = (Name,Address) type Name = String data Address = None | Addr String @ \eprog Type synonyms do not define new types, but simply give new names for existing types. For example, the type @Person -> Name@ is precisely equivalent to @(String,Address) -> String@. The new names are often shorter than the types they are synonymous with, but this is not the only purpose of type synonyms: they can also improve readability of programs by being more mnemonic; indeed, the above examples highlight this. We can even give new names to polymorphic types: \bprog @ type AssocList a b = [(a,b)] @ \eprog This is the type of ``association lists'' which associate values of type @a@ with those of type @b@. \subsection{Built-in Types Are Not Special} \label{tut-built-ins} Earlier we introduced several ``built-in'' types such as lists, tuples, integers, and characters. We have also shown how new user-defined types can be defined. Aside from special syntax, are the built-in types in any way more special than the user-defined ones? The answer is {\em no}. The special syntax is for convenience and for consistency with historical convention, but has no semantic consequences. We can emphasize this point by considering what the type declarations would look like for these built-in types if in fact we were allowed to use the special syntax in defining them. For example, the @Char@ type might be written as: \bprog @ data Char = 'a' | 'b' | 'c' | ... -- This is not valid | 'A' | 'B' | 'C' | ... -- Haskell code! | '1' | '2' | '3' | ... ... @ \eprog These constructor names are not syntactically valid; to fix them we would have to write something like: \bprog @ data Char = Ca | Cb | Cc | ... | CA | CB | CC | ... | C1 | C2 | C3 | ... ... @ \eprog Even though these constructors are more concise, they are quite unconventional for representing characters. In any case, writing ``pseudo-Haskell'' code in this way helps us to see through the special syntax. We see now that @Char@ is just an enumerated type consisting of a large number of nullary constructors. Thinking of @Char@ in this way makes it clear that we can pattern-match against characters in function definitions, just as we would expect to be able to do so for any of a type's constructors. \syn{This example also demonstrates the use of {\em comments} in Haskell; the characters @--@ and all subsequent characters to the end of the line are ignored. Haskell also permits {\em nested} comments which have the form @{-@$\ldots$@-}@ and can appear anywhere (\see{lexemes}).} Similarly, we could define @Int@ (fixed precision integers) and @Integer@ by: \bprog @ data Int = -65532 | ... | -1 | 0 | 1 | ... | 65532 -- more pseudo-code data Integer = ... -2 | -1 | 0 | 1 | 2 ... @ \eprog where @-65532@ and @65532@, say, are the maximum and minimum fixed precision integers for a given implementation. @Int@ is a much larger enumeration than @Char@, but it's still finite! In contrast, the pseudo-code for @Integer@ is intended to convey an {\em infinite} enumeration. Tuples are also easy to define playing this game: \bprog @ data (a,b) = (a,b) -- more pseudo-code data (a,b,c) = (a,b,c) data (a,b,c,d) = (a,b,c,d) . . . . . . @ \eprog Each declaration above defines a tuple type of a particular length, with @(...)@ playing a role in both the expression syntax (as data constructor) and type-expression syntax (as type constructor). The vertical dots after the last declaration are intended to convey an infinite number of such declarations, reflecting the fact that tuples of all lengths are allowed in Haskell. Lists are also easily handled, and more interestingly, they are recursive: \bprog @ data [a] = [] | a : [a] -- more pseudo-code @ \eprog We can now see clearly what we described about lists earlier: @[]@ is the empty list, and @:@ is the infix list constructor; thus @[1,2,3]@ must be equivalent to the list @1:2:3:[]@. (@:@ is right associative.) The type of @[]@ is @[a]@, and the type of @:@ is @a->[a]->[a]@. \syn{The way ``@:@'' is defined here is actually legal syntax---infix constructors are permitted in @data@ declarations, and are distinguished from infix operators (for pattern-matching purposes) by the fact that they must begin with a ``@:@'' (a property trivially satisfied by ``@:@'').} At this point the reader should note carefully the differences between tuples and lists, which the above definitions make abundantly clear. In particular, note the recursive nature of the list type whose elements are homogeneous and of arbitrary length, and the non-recursive nature of a (particular) tuple type whose elements are heterogeneous and of fixed length. The typing rules for tuples and lists should now also be clear: For $@(@e_1@,@e_2@,@\ldots@,@e_n@)@,\ n\geq2$, if $t_i$ is the type of $e_i$, then the type of the tuple is $@(@t_1@,@t_2@,@\ldots@,@t_n@)@$. For $@[@e_1@,@e_2@,@\ldots@,@e_n@]@,\ n\geq0$, each $e_i$ must have the same type $t$, and the type of the list is @[@$t$@]@. \subsubsection{List Comprehensions and Arithmetic Sequences} \label{tut-list-comps} As with Lisp dialects, lists are pervasive in Haskell, and as with other functional languages, there is yet more syntactic sugar to aid in their creation. Aside from the constructors for lists just discussed, Haskell provides an expression known as a {\em list comprehension} that is best explained by example: \bprog @ [ f x | x <- xs ] @ \eprog This expression can intuitively be read as ``the list of all @f x@ such that @x@ is drawn from @xs@.'' The similarity to set notation is not a coincidence. The phrase @x <- xs@ is called a {\em generator}, of which more than one is allowed, as in: \bprog @ [ (x,y) | x <- xs, y <- ys ] @ \eprog This list comprehension forms the cartesian product of the two lists @xs@ and @ys@. The elements are selected as if the generators were ``nested'' from left to right (with the rightmost generator varying fastest); thus, if @xs@ is @[1,2]@ and @ys@ is @[3,4]@, the result is @[(1,3),(1,4),(2,3),(2,4)]@. Besides generators, boolean expressions called {\em guards} are permitted. Guards place constraints on the elements generated. For example, here is a concise definition of everybody's favorite sorting algorithm: \bprog @ quicksort [] = [] quicksort (x:xs) = quicksort [y | y <- xs, y=x] @ \eprog To further support the use of lists, Haskell has special syntax for {\em arithmetic sequences}, which are best explained by a series of examples: \[\ba{lcl} @[1..10]@ \ \ \ &\red&\ \ \ @[1,2,3,4,5,6,7,8,9,10]@\\ @[1,3..10]@\ \ \ &\red&\ \ \ @[1,3,5,7,9]@\\ % @[1..]@ \ \ \ &\red&\ \ \ @[1,2,3,4,5, ...@\ \ \ \ \ % \mbox{(infinite sequence)}\\ @[1,3..]@ \ \ \ &\red&\ \ \ @[1,3,5,7,9, ...@\ \ \ \ \ \mbox{(infinite sequence)}\\ \ea\] More will be said about arithmetic sequences in Section \ref{tut-enum-classes}, and ``infinite lists'' in Section \ref{tut-infinite}. \subsubsection{Strings} \label{tut-strings} As another example of syntactic sugar for built-in types, we note that the literal string @"hello"@ is actually shorthand for the list of characters @['h','e','l','l','o']@. Indeed, the type of @"hello"@ is @String@, where @String@ is a predefined type synonym (that we gave as an earlier example): \bprog @ type String = [Char] @ \eprog This means we can use predefined polymorphic list functions to operate on strings. For example: \[ @"hello" ++ " world"@\ \ \ \ \red\ \ \ \ @"hello world"@ \] %**~footer haskell-98-tutorial-sources/haskell-tutorial.verb0100644000106400000620000000415706774446522020575 0ustar jcpftp \documentclass[twoside,11pt]{article} \textheight=8.5in \textwidth=6.5in \topmargin=-.3in \oddsidemargin=0in \evensidemargin=0in \parskip=6pt plus2pt minus2pt \pagestyle{headings} \input{report-refs} \usepackage{epsf} % \renewcommand{\thepage}{T-\arabic{page}} \newcommand{\folks}[1]{\begin{quote}\sf#1\end{quote}} \newcommand{\bc}{\begin{center}} \newcommand{\ec}{\end{center}} \newcommand{\be}{\begin{enumerate}} \newcommand{\ee}{\end{enumerate}} \newcommand{\ba}{\begin{array}} \newcommand{\ea}{\end{array}} \newcommand{\x}{\times} \newcommand{\lam}{\lambda} \newcommand{\la}{\leftarrow} \newcommand{\ra}{\rightarrow} \newcommand{\red}{\Rightarrow} \newcommand{\see}[1]{\S\ref{#1}} \newcommand{\syn}[1]{[#1]} \newcommand{\bprog}{% \par\noindent\begin{tabular}{@@{\hspace*{17pt}}l@@{}}} \newcommand{\eprog}{% \end{tabular}\\[\parskip]} \newcommand{\eprogNoSkip}{% \end{tabular}} \newcommand{\anchor}[2]{#2} \begin{document} \title{A Gentle Introduction to Haskell 98} \author{Paul Hudak\\ Yale University\\ Department of Computer Science \and John Peterson\\ Yale University\\ Department of Computer Science \and Joseph H. Fasel\\ University of California\\ Los Alamos National Laboratory} \date{October, 1999} \maketitle Copyright \copyright\ 1999 Paul Hudak, John Peterson and Joseph Fasel Permission is hereby granted, free of charge, to any person obtaining a copy of ``A Gentle Introduction to Haskell'' (the Text), to deal in the Text without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Text, and to permit persons to whom the Text is furnished to do so, subject to the following condition: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Text. \input{intro} \input{goodies} \input{functions} \input{patterns} \input{classes} \input{moretypes} \input{io} \input{stdclasses} \input{monads} \input{numbers} \input{modules} \input{pitfalls} \input{arrays} \input{end} \bibliographystyle{plain} \bibliography{tut} \end{document} haskell-98-tutorial-sources/intro.verb0100644000106400000620000000667007121451342016425 0ustar jcpftp%**A Gentle Introduction to Haskell: Introduction %**~sheader \section{Introduction} \label{tut-intro} Our purpose in writing this tutorial is not to teach programming, nor even to teach functional programming. Rather, it is intended to serve as a supplement to the Haskell Report \cite{haskell-98}, which is otherwise a rather dense technical exposition. Our goal is to provide a gentle introduction to Haskell for someone who has experience with at least one other language, preferably a functional language (even if only an ``almost-functional'' language such as ML or Scheme). If the reader wishes to learn more about the functional programming style, we highly recommend Bird's text {\em Introduction to Functional Programming} \cite{bird98} or Davie's {\em An Introduction to Functional Programming Systems Using Haskell} \cite{davie92}. For a useful survey of functional programming languages and techniques, including some of the language design principles used in Haskell, see \cite{huda89a}. The Haskell language has evolved significantly since its birth in 1987. This tutorial deals with \anchor{http://haskell.org/report} {Haskell 98}. Older versions of the language are now obsolete; Haskell users are encouraged to use Haskell 98. There are also many extensions to Haskell 98 that have been widely implemented. These are not yet a formal part of the Haskell language and are not covered in this tutorial. Our general strategy for introducing language features is this: motivate the idea, define some terms, give some examples, and then point to the Report for details. We suggest, however, that the reader completely ignore the details until the {\em Gentle Introduction} has been completely read. On the other hand, Haskell's Standard Prelude (in Appendix A of the Report and the standard libraries (found in the \anchor{http://haskell.org/library} Library Report~\cite{haskell-libs}) contain lots of useful examples of Haskell code; we encourage a thorough reading once this tutorial is completed. This will not only give the reader a feel for what real Haskell code looks like, but will also familiarize her with Haskell's standard set of predefined functions and types. Finally, the Haskell web site, \anchor{http://haskell.org}{{\tt http://haskell.org}}, has a wealth of information about the Haskell language and its implementations. \syn{We have also taken the course of not laying out a plethora of lexical syntax rules at the outset. Rather, we introduce them incrementally as our examples demand, and enclose them in brackets, as with this paragraph. This is in stark contrast to the organization of the Report, although the Report remains the authoritative source for details (references such as ``\S 2.1'' refer to sections in the Report).} Haskell is a {\em typeful} programming language:\footnote{Coined by Luca Cardelli.} types are pervasive, and the newcomer is best off becoming well aware of the full power and complexity of Haskell's type system from the outset. For those whose only experience is with relatively ``untypeful'' languages such as Perl, Tcl, or Scheme, this may be a difficult adjustment; for those familiar with Java, C, Modula, or even ML, the adjustment should be easier but still not insignificant, since Haskell's type system is different and somewhat richer than most. In any case, ``typeful programming'' is part of the Haskell programming experience, and cannot be avoided. % \maybeInclude{intro-extra} %**~sfooter haskell-98-tutorial-sources/io.verb0100644000106400000620000004140507065470201015676 0ustar jcpftp%**A Gentle Introduction to Haskell: IO %**~header \section{Input/Output} \label{tut-io} The I/O system in Haskell is purely functional, yet has all of the expressive power found in conventional programming languages. In imperative languages, programs proceed via "actions" which examine and modify the current state of the world. Typical actions include reading and setting global variables, writing files, reading input, and opening windows. Such actions are also a part of Haskell but are cleanly separated from the purely functional core of the language. Haskell's I/O system is built around a somewhat daunting mathematical foundation: the "monad". However, understanding of the underlying monad theory is not necessary to program using the I/O system. Rather, monads are a conceptual structure into which I/O happens to fit. It is no more necessary to understand monad theory to perform Haskell I/O than it is to understand group theory to do simple arithmetic. A detailed explanation of monads is found in Section \ref{tut-monads}. The monadic operators that the I/O system is built upon are also used for other purposes; we will look more deeply into monads later. For now, we will avoid the term monad and concentrate on the use of the I/O system. It's best to think of the I/O monad as simply an abstract data type. Actions are defined rather than invoked within the expression language of Haskell. Evaluating the definition of an action doesn't actually cause the action to happen. Rather, the invocation of actions takes place outside of the expression evaluation we have considered up to this point. Actions are either atomic, as defined in system primitives, or are a sequential composition of other actions. The I/O monad contains primitives which build composite actions, a process similar to joining statements in sequential order using `@;@' in other languages. Thus the monad serves as the glue which binds together the actions in a program. \subsection{Basic I/O Operations} Every I/O action returns a value. In the type system, the return value is `tagged' with @IO@ type, distinguishing actions from other values. For example, the type of the function @getChar@ is: \bprog @ getChar :: IO Char @ \eprog The @IO Char@ indicates that @getChar@, when invoked, performs some action which returns a character. Actions which return no interesting values use the unit type, @()@. For example, the @putChar@ function: \bprog @ putChar :: Char -> IO () @ \eprog takes a character as an argument but returns nothing useful. The unit type is similar to @void@ in other languages. Actions are sequenced using an operator that has a rather cryptic name: @>>=@ (or `bind'). Instead of using this operator directly, we choose some syntactic sugar, the @do@ notation, to hide these sequencing operators under a syntax resembling more conventional languages. The @do@ notation can be trivially expanded to @>>=@, as described in \see{do-expressions}. The keyword @do@ introduces a sequence of statements which are executed in order. A statement is either an action, a pattern bound to the result of an action using @<-@, or a set of local definitions introduced using @let@. The @do@ notation uses layout in the same manner as @let@ or @where@ so we can omit braces and semicolons with proper indentation. Here is a simple program to read and then print a character: \bprog @ main :: IO () main = do c <- getChar putChar c @ \eprog The use of the name @main@ is important: @main@ is defined to be the entry point of a Haskell program (similar to the @main@ function in C), and must have an @IO@ type, usually @IO ()@. (The name @main@ is special only in the module @Main@; we will have more to say about modules later.) This program performs two actions in sequence: first it reads in a character, binding the result to the variable c, and then prints the character. Unlike a @let@ expression where variables are scoped over all definitions, the variables defined by @<-@ are only in scope in the following statements. There is still one missing piece. We can invoke actions and examine their results using @do@, but how do we return a value from a sequence of actions? For example, consider the @ready@ function that reads a character and returns @True@ if the character was a `y': \bprog @ ready :: IO Bool ready = do c <- getChar c == 'y' -- Bad!!! @ \eprog This doesn't work because the second statement in the `do' is just a boolean value, not an action. We need to take this boolean and create an action that does nothing but return the boolean as its result. The @return@ function does just that: \bprog @ return :: a -> IO a @ \eprog The @return@ function completes the set of sequencing primitives. The last line of @ready@ should read @return (c == 'y')@. We are now ready to look at more complicated I/O functions. First, the function @getLine@: \bprog @ getLine :: IO String getLine = do c <- getChar if c == '\n' then return "" else do l <- getLine return (c:l) @ \eprog Note the second @do@ in the else clause. Each @do@ introduces a single chain of statements. Any intervening construct, such as the @if@, must use a new @do@ to initiate further sequences of actions. The @return@ function admits an ordinary value such as a boolean to the realm of I/O actions. What about the other direction? Can we invoke some I/O actions within an ordinary expression? For example, how can we say @x + print y@ in an expression so that @y@ is printed out as the expression evaluates? The answer is that we can't! It is "not" possible to sneak into the imperative universe while in the midst of purely functional code. Any value `infected' by the imperative world must be tagged as such. A function such as \bprog @ f :: Int -> Int -> Int @ \eprog absolutely cannot do any I/O since @IO@ does not appear in the returned type. This fact is often quite distressing to programmers used to placing print statements liberally throughout their code during debugging. There are, in fact, some unsafe functions available to get around this problem but these are better left to advanced programmers. Debugging packages (like @Trace@) often make liberal use of these `forbidden functions' in an entirely safe manner. \subsection{Programming With Actions} I/O actions are ordinary Haskell values: they may be passed to functions, placed in structures, and used as any other Haskell value. Consider this list of actions: \bprog @ todoList :: [IO ()] todoList = [putChar 'a', do putChar 'b' putChar 'c', do c <- getChar putChar c] @ \eprog This list doesn't actually invoke any actions---it simply holds them. To join these actions into a single action, a function such as @sequence_@ is needed: \bprog @ sequence_ :: [IO ()] -> IO () sequence_ [] = return () sequence_ (a:as) = do a sequence as @ \eprog This can be simplified by noting that @do x;y@ is expanded to @x >> y@ (see Section \ref{tut-monadic-classes}). This pattern of recursion is captured by the @foldr@ function (see the Prelude for a definition of @foldr@); a better definition of @sequence_@ is: \bprog @ sequence_ :: [IO ()] -> IO () sequence_ = foldr (>>) (return ()) @ \eprog The @do@ notation is a useful tool but in this case the underlying monadic operator, @>>@, is more appropriate. An understanding of the operators upon which @do@ is built is quite useful to the Haskell programmer. The @sequence_@ function can be used to construct @putStr@ from @putChar@: \bprog @ putStr :: String -> IO () putStr s = sequence_ (map putChar s) @ \eprog One of the differences between Haskell and conventional imperative programming can be seen in @putStr@. In an imperative language, mapping an imperative version of @putChar@ over the string would be sufficient to print it. In Haskell, however, the @map@ function does not perform any action. Instead it creates a list of actions, one for each character in the string. The folding operation in @sequence_@ uses the @>>@ function to combine all of the individual actions into a single action. The @return ()@ used here is quite necessary -- @foldr@ needs a null action at the end of the chain of actions it creates (especially if there are no characters in the string!). The Prelude and the libraries contains many functions which are useful for sequencing I/O actions. These are usually generalized to arbitrary monads; any function with a context including @Monad m =>@ works with the @IO@ type. \subsection{Exception Handling} So far, we have avoided the issue of exceptions during I/O operations. What would happen if @getChar@ encounters an end of file?\footnote{We use the term "error" for "\bot": a condition which cannot be recovered from such as non-termination or pattern match failure. Exceptions, on the other hand, can be caught and handled within the I/O monad.} To deal with exceptional conditions such as `file not found' within the I/O monad, a handling mechanism is used, similar in functionality to the one in standard ML. No special syntax or semantics are used; exception handling is part of the definition of the I/O sequencing operations. Errors are encoded using a special data type, @IOError@. This type represents all possible exceptions that may occur within the I/O monad. This is an abstract type: no constructors for @IOError@ are available to the user. Predicates allow @IOError@ values to be queried. For example, the function \bprog @ isEOFError :: IOError -> Bool @ \eprog determines whether an error was caused by an end-of-file condition. By making @IOError@ abstract, new sorts of errors may be added to the system without a noticeable change to the data type. The function @isEOFError@ is defined in a separate library, @IO@, and must be explicitly imported into a program. An {\em exception handler} has type @IOError -> IO a@. The @catch@ function associates an exception handler with an action or set of actions: \bprog @ catch :: IO a -> (IOError -> IO a) -> IO a @ \eprog The arguments to @catch@ are an action and a handler. If the action succeeds, its result is returned without invoking the handler. If an error occurs, it is passed to the handler as a value of type @IOError@ and the action associated with the handler is then invoked. For example, this version of @getChar@ returns a newline when an error is encountered: \bprog @ getChar' :: IO Char getChar' = getChar `catch` (\e -> return '\n') @ \eprog This is rather crude since it treats all errors in the same manner. If only end-of-file is to be recognized, the error value must be queried: \bprog @ getChar' :: IO Char getChar' = getChar `catch` eofHandler where eofHandler e = if isEofError e then return '\n' else ioError e @ \eprog The @ioError@ function used here throws an exception on to the next exception handler. The type of @ioError@ is \bprog @ ioError :: IOError -> IO a @ \eprog It is similar to @return@ except that it transfers control to the exception handler instead of proceeding to the next I/O action. Nested calls to @catch@ are permitted, and produce nested exception handlers. Using @getChar'@, we can redefine @getLine@ to demonstrate the use of nested handlers: \bprog @ getLine' :: IO String getLine' = catch getLine'' (\err -> return ("Error: " ++ show err)) where getLine'' = do c <- getChar' if c == '\n' then return "" else do l <- getLine' return (c:l) @ \eprog The nested error handlers allow @getChar'@ to catch end of file while any other error results in a string starting with @"Error: "@ from @getLine'@. For convenience, Haskell provides a default exception handler at the topmost level of a program that prints out the exception and terminates the program. \subsection{Files, Channels, and Handles} Aside from the I/O monad and the exception handling mechanism it provides, I/O facilities in Haskell are for the most part quite similar to those in other languages. Many of these functions are in the @IO@ library instead of the Prelude and thus must be explicitly imported to be in scope (modules and importing are discussed in Section~\ref{tut-modules}). Also, many of these functions are discussed in the Library Report instead of the main report. Opening a file creates a "handle" (of type @Handle@) for use in I/O transactions. Closing the handle closes the associated file: \bprog @ type FilePath = String -- path names in the file system openFile :: FilePath -> IOMode -> IO Handle hClose :: Handle -> IO () data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode @ \eprog Handles can also be associated with "channels": communication ports not directly attached to files. A few channel handles are predefined, including @stdin@ (standard input), @stdout@ (standard output), and @stderr@ (standard error). Character level I/O operations include @hGetChar@ and @hPutChar@, which take a handle as an argument. The @getChar@ function used previously can be defined as: \bprog @ getChar = hGetChar stdin @ \eprog Haskell also allows the entire contents of a file or channel to be returned as a single string: \bprog @ getContents :: Handle -> IO String @ \eprog Pragmatically, it may seem that @getContents@ must immediately read an entire file or channel, resulting in poor space and time performance under certain conditions. However, this is not the case. The key point is that @getContents@ returns a ``lazy'' (i.e. non-strict) list of characters (recall that strings are just lists of characters in Haskell), whose elements are read ``by demand'' just like any other list. An implementation can be expected to implement this demand-driven behavior by reading one character at a time from the file as they are required by the computation. In this example, a Haskell program copies one file to another: \bprog @ main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode toHandle <- getAndOpenFile "Copy to: " WriteMode contents <- hGetContents fromHandle hPutStr toHandle contents hClose toHandle putStr "Done." getAndOpenFile :: String -> IOMode -> IO Handle getAndOpenFile prompt mode = do putStr prompt name <- getLine catch (openFile name mode) (\_ -> do putStrLn ("Cannot open "++ name ++ "\n") getAndOpenFile prompt mode) @ \eprog By using the lazy @getContents@ function, the entire contents of the file need not be read into memory all at once. If @hPutStr@ chooses to buffer the output by writing the string in fixed sized blocks of characters, only one block of the input file needs to be in memory at once. The input file is closed implicitly when the last character has been read. \subsection{Haskell and Imperative Programming} As a final note, I/O programming raises an important issue: this style looks suspiciously like ordinary imperative programming. For example, the @getLine@ function: \bprog @ getLine = do c <- getChar if c == '\n' then return "" else do l <- getLine return (c:l) @ \eprog bears a striking similarity to imperative code (not in any real language) : \bprog @ function getLine() { c := getChar(); if c == `\n` then return "" else {l := getLine(); return c:l}} @ \eprog So, in the end, has Haskell simply re-invented the imperative wheel? In some sense, yes. The I/O monad constitutes a small imperative sub-language inside Haskell, and thus the I/O component of a program may appear similar to ordinary imperative code. But there is one important difference: There is no special semantics that the user needs to deal with. In particular, equational reasoning in Haskell is not compromised. The imperative feel of the monadic code in a program does not detract from the functional aspect of Haskell. An experienced functional programmer should be able to minimize the imperative component of the program, only using the I/O monad for a minimal amount of top-level sequencing. The monad cleanly separates the functional and imperative program components. In contrast, imperative languages with functional subsets do not generally have any well-defined barrier between the purely functional and imperative worlds. %**~footer haskell-98-tutorial-sources/modules.verb0100644000106400000620000002027307065471134016745 0ustar jcpftp%**A Gentle Introduction to Haskell: Modules %**~header \section{Modules} \label{tut-modules} A Haskell program consists of a collection of {\em modules}. A module in Haskell serves the dual purpose of controlling name-spaces and creating abstract data types. The top level of a module contains any of the various declarations we have discussed: fixity declarations, data and type declarations, class and instance declarations, type signatures, function definitions, and pattern bindings. Except for the fact that import declarations (to be described shortly) must appear first, the declarations may appear in any order (the top-level scope is mutually recursive). Haskell's module design is relatively conservative: the name-space of modules is completely flat, and modules are in no way ``first-class.'' Module names are alphanumeric and must begin with an uppercase letter. There is no formal connection between a Haskell module and the file system that would (typically) support it. In particular, there is no connection between module names and file names, and more than one module could conceivably reside in a single file (one module may even span several files). Of course, a particular implementation will most likely adopt conventions that make the connection between modules and files more stringent. Technically speaking, a module is really just one big declaration which begins with the keyword @module@; here's an example for a module whose name is @Tree@: \bprog @ module Tree ( Tree(Leaf,Branch), fringe ) where data Tree a = Leaf a | Branch (Tree a) (Tree a) fringe :: Tree a -> [a] fringe (Leaf x) = [x] fringe (Branch left right) = fringe left ++ fringe right @ \eprog The type @Tree@ and the function @fringe@ should be familiar; they were given as examples in Section \ref{tut-recursive-types}. \syn{Because of the @where@ keyword, layout is active at the top level of a module, and thus the declarations must all line up in the same column (typically the first). Also note that the module name is the same as that of the type; this is allowed.} This module explicitly {\em exports} @Tree@, @Leaf@, @Branch@, and @fringe@. If the export list following the @module@ keyword is omitted, {\em all} of the names bound at the top level of the module would be exported. (In the above example everything is explicitly exported, so the effect would be the same.) Note that the name of a type and its constructors have be grouped together, as in @Tree(Leaf,Branch)@. As short-hand, we could also write @Tree(..)@. Exporting a subset of the constructors is also possible. The names in an export list need not be local to the exporting module; any name in scope may be listed in an export list. The @Tree@ module may now be {\em imported} into some other module: \bprog @ module Main (main) where import Tree ( Tree(Leaf,Branch), fringe ) main = print (fringe (Branch (Leaf 1) (Leaf 2))) @ \eprog The various items being imported into and exported out of a module are called {\em entities}. Note the explicit import list in the import declaration; omitting it would cause all entities exported from @Tree@ to be imported. \subsection{Qualified Names} There is an obvious problem with importing names directly into the namespace of module. What if two imported modules contain different entities with the same name? Haskell solves this problem using "qualified names". An import declaration may use the @qualified@ keyword to cause the imported names to be prefixed by the name of the module imported. These prefixes are followed by the `@.@' character without intervening whitespace. \syn{Qualifiers are part of the lexical syntax. Thus, @A.x@ and @A . x@ are quite different: the first is a qualified name and the second a use of the infix `@.@' function.} For example, using the @Tree@ module introduced above: \bprog @ module Fringe(fringe) where import Tree(Tree(..)) fringe :: Tree a -> [a] -- A different definition of fringe fringe (Leaf x) = [x] fringe (Branch x y) = fringe x module Main where import Tree ( Tree(Leaf,Branch), fringe ) import qualified Fringe ( fringe ) main = do print (fringe (Branch (Leaf 1) (Leaf 2))) print (Fringe.fringe (Branch (Leaf 1) (Leaf 2))) @ \eprog Some Haskell programmers prefer to use qualifiers for all imported entities, making the source of each name explicit with every use. Others prefer short names and only use qualifiers when absolutely necessary. Qualifiers are used to resolve conflicts between different entities which have the same name. But what if the same entity is imported from more than one module? Fortunately, such name clashes are allowed: an entity can be imported by various routes without conflict. The compiler knows whether entities from different modules are actually the same. \subsection{Abstract Data Types} \label{tut-ADTs} Aside from controlling namespaces, modules provide the only way to build abstract data types (ADTs) in Haskell. For example, the characteristic feature of an ADT is that the {\em representation type} is {\em hidden}; all operations on the ADT are done at an abstract level which does not depend on the representation. For example, although the @Tree@ type is simple enough that we might not normally make it abstract, a suitable ADT for it might include the following operations: \bprog @ data Tree a -- just the type name leaf :: a -> Tree a branch :: Tree a -> Tree a -> Tree a cell :: Tree a -> a left, right :: Tree a -> Tree a isLeaf :: Tree a -> Bool @ \eprog A module supporting this is: \bprog @ module TreeADT (Tree, leaf, branch, cell, left, right, isLeaf) where data Tree a = Leaf a | Branch (Tree a) (Tree a) leaf = Leaf branch = Branch cell (Leaf a) = a left (Branch l r) = l right (Branch l r) = r isLeaf (Leaf _) = True isLeaf _ = False @ \eprog Note in the export list that the type name @Tree@ appears alone (i.e.~without its constructors). Thus @Leaf@ and @Branch@ are not exported, and the only way to build or take apart trees outside of the module is by using the various (abstract) operations. Of course, the advantage of this information hiding is that at a later time we could {\em change} the representation type without affecting users of the type. \subsection{More Features} \label{tut-rules} Here is a brief overview of some other aspects of the module system. See the report for more details. \begin{itemize} \item An @import@ declaration may selectively hide entities using a @hiding@ clause in the import declaration. This is useful for explicitly excluding names that are used for other purposes without having to use qualifiers for other imported names from the module. \item An @import@ may contain an @as@ clause to specify a different qualifier than the name of the importing module. This can be used to shorten qualifiers from modules with long names or to easily adapt to a change in module name without changing all qualifiers. \item Programs implicitly import the @Prelude@ module. An explicit import of the Prelude overrides the implicit import of all Prelude names. Thus, \bprog @ import Prelude hiding length @ \eprog will not import @length@ from the Standard Prelude, allowing the name @length@ to be defined differently. \item Instance declarations are not explicitly named in import or export lists. Every module exports all of its instance declarations and every import brings all instance declarations into scope. \item Class methods may be named either in the manner of data constructors, in parentheses following the class name, or as ordinary variables. \end{itemize} Although Haskell's module system is relatively conservative, there are many rules concerning the import and export of values. Most of these are obvious---for instance, it is illegal to import two different entities having the same name into the same scope. Other rules are not so obvious---for example, for a given type and class, there cannot be more than one @instance@ declaration for that combination of type and class anywhere in the program. The reader should read the Report for details (\see{modules}). %**~footer haskell-98-tutorial-sources/monads.verb0100644000106400000620000005612607121451365016561 0ustar jcpftp%**A Gentle Introduction to Haskell: About Monads %**~header \section{About Monads} \label{tut-monads} Many newcomers to Haskell are puzzled by the concept of {\em monads}. Monads are frequently encountered in Haskell: the IO system is constructed using a monad, a special syntax for monads has been provided (@do@ expressions), and the standard libraries contain an entire module dedicated to monads. In this section we explore monadic programming in more detail. This section is perhaps less ``gentle'' than the others. Here we address not only the language features that involve monads but also try to reveal the bigger picture: why monads are such an important tool and how they are used. There is no single way of explaining monads that works for everyone; more explanations can be found at {\tt haskell.org}. Another good introduction to practical programming using monads is Wadler's {\em Monads for Functional Programming}~\cite{wadler:mffp}. \subsection{Monadic Classes} \label{tut-monadic-classes} The Prelude contains a number of classes defining monads are they are used in Haskell. These classes are based on the monad construct in category theory; whilst the category theoretic terminology provides the names for the monadic classes and operations, it is not necessary to delve into abstract mathematics to get an intuitive understanding of how to use the monadic classes. A monad is constructed on top of a polymorphic type such as @IO@. The monad itself is defined by instance declarations associating the type with the some or all of the monadic classes, @Functor@, @Monad@, and @MonadPlus@. None of the monadic classes are derivable. In addition to @IO@, two other types in the Prelude are members of the monadic classes: lists (@[]@) and @Maybe@. Mathematically, monads are governed by set of {\em laws} that should hold for the monadic operations. This idea of laws is not unique to monads: Haskell includes other operations that are governed, at least informally, by laws. For example, @x /= y@ and @not (x == y)@ ought to be the same for any type of values being compared. However, there is no guarantee of this: both @==@ and @/=@ are separate methods in the @Eq@ class and there is no way to assure that @==@ and @=/@ are related in this manner. In the same sense, the monadic laws presented here are not enforced by Haskell, but ought be obeyed by any instances of a monadic class. The monad laws give insight into the underlying structure of monads: by examining these laws, we hope to give a feel for how monads are used. The @Functor@ class, already discussed in section \ref{tut-type-classes}, defines a single operation: @fmap@. The map function applies an operation to the objects inside a container (polymorphic types can be thought of as containers for values of another type), returning a container of the same shape. These laws apply to @fmap@ in the class @Functor@: \[\ba{lcl} @fmap id@&=&@id@\\ @fmap (f . g)@&=&@fmap f . fmap g@\\ \ea\] These laws ensure that the container shape is unchanged by @fmap@ and that the contents of the container are not re-arranged by the mapping operation. The @Monad@ class defines two basic operators: @>>=@ (bind) and @return@. \bprog @ infixl 1 >>, >>= class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a m >> k = m >>= \_ -> k @ \eprog The bind operations, @>>@ and @>>=@, combine two monadic values while the @return@ operation injects a value into the monad (container). The signature of @>>=@ helps us to understand this operation: @ma >>= \v -> mb@ combines a monadic value @ma@ containing values of type @a@ and a function which operates on a value @v@ of type @a@, returning the monadic value @mb@. The result is to combine @ma@ and @mb@ into a monadic value containing @b@. The @>>@ function is used when the function does not need the value produced by the first monadic operator. The precise meaning of binding depends, of course, on the monad. For example, in the IO monad, @x >>= y@ performs two actions sequentially, passing the result of the first into the second. For the other built-in monads, lists and the @Maybe@ type, these monadic operations can be understood in terms of passing zero or more values from one calculation to the next. We will see examples of this shortly. The @do@ syntax provides a simple shorthand for chains of monadic operations. The essential translation of @do@ is captured in the following two rules: \bprog @ do e1 ; e2 = e1 >> e2 do p <- e1; e2 = e1 >>= \p -> e2 @ \eprog When the pattern in this second form of @do@ is refutable, pattern match failure calls the @fail@ operation. This may raise an error (as in the @IO@ monad) or return a ``zero'' (as in the list monad). Thus the more complex translation is \bprog @ do p <- e1; e2 = e1 >>= (\v -> case v of p -> e2; _ -> fail "s") @ \eprog where @"s"@ is a string identifying the location of the @do@ statement for possible use in an error message. For example, in the I/O monad, an action such as @'a' <- getChar@ will call @fail@ if the character typed is not 'a'. This, in turn, terminates the program since in the I/O monad @fail@ calls @error@. The laws which govern @>>=@ and @return@ are: \[\ba{lcl} @return a >>= k@&=&@k a@ \\ @m >>= return@&=&@m@ \\ @xs >>= return . f@&=&@fmap f xs@\\ @m >>= (\x -> k x >>= h)@&=&@(m >>= k) >>= h@\\ \ea\] The class @MonadPlus@ is used for monads that have a "zero" element and a "plus" operation: \bprog @ class (Monad m) => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a @ \eprog The zero element obeys the following laws: \[\ba{lcl} @m >>= \x -> mzero@&=&@mzero@\\ @mzero >>= m@&=&@mzero@\\ \ea\] For lists, the zero value is @[]@, the empty list. The I/O monad has no zero element and is not a member of this class. The laws governing the @mplus@ operator are as follows: \[\ba{lcl} @m `mplus` mzero@&=&@m@\\ @mzero `mplus` m@&=&@m@\\ \ea\] The @mplus@ operator is ordinary list concatenation in the list monad. \subsection{Built-in Monads} Given the monadic operations and the laws that govern them, what can we build? We have already examined the I/O monad in detail so we start with the two other built-in monads. For lists, monadic binding involves joining together a set of calculations for each value in the list. When used with lists, the signature of @>>=@ becomes: \bprog @ (>>=) :: [a] -> (a -> [b]) -> [b] @ \eprog That is, given a list of @a@'s and a function that maps an @a@ onto a list of @b@'s, binding applies this function to each of the @a@'s in the input and returns all of the generated @b@'s concatenated into a list. The @return@ function creates a singleton list. These operations should already be familiar: list comprehensions can easily be expressed using the monadic operations defined for lists. These following three expressions are all different syntax for the same thing: \bprog @ [(x,y) | x <- [1,2,3] , y <- [1,2,3], x /= y] do x <- [1,2,3] y <- [1,2,3] True <- return (x /= y) return (x,y) [1,2,3] >>= (\ x -> [1,2,3] >>= (\y -> return (x/=y) >>= (\r -> case r of True -> return (x,y) _ -> fail ""))) @ \eprog This definition depends on the definition of @fail@ in this monad as the empty list. Essentially, each @<-@ is generating a set of values which is passed on into the remainder of the monadic computation. Thus @x <- [1,2,3]@ invokes the remainder of the monadic computation three times, once for each element of the list. The returned expression, @(x,y)@, will be evaluated for all possible combinations of bindings that surround it. In this sense, the list monad can be thought of as describing functions of multi-valued arguments. For example, this function: \bprog @ mvLift2 :: (a -> b -> c) -> [a] -> [b] -> [c] mvLift2 f x y = do x' <- x y' <- y return (f x' y') @ \eprog turns an ordinary function of two arguments (@f@) into a function over multiple values (lists of arguments), returning a value for each possible combination of the two input arguments. For example, \[\ba{lcl} @mvLift2 (+) [1,3] [10,20,30]@ \ \ \ &\red&\ \ \ @[11,21,31,13,23,33]@\\ @mvLift2 (\a b->[a,b]) "ab" "cd"@ \ \ \ &\red&\ \ \ @["ac","ad","bc","bd"]@\\ @mvLift2 (*) [1,2,4] []@\ \ \ &\red&\ \ \ @[]@\\ \ea\] This function is a specialized version of the @LiftM2@ function in the monad library. You can think of it as transporting a function from outside the list monad, @f@, into the list monad in which computations take on multiple values. The monad defined for @Maybe@ is similar to the list monad: the value @Nothing@ serves as @[]@ and @Just x@ as @[x]@. \subsection{Using Monads} Explaining the monadic operators and their associated laws doesn't really show what monads are good for. What they really provide is {\em modularity}. That is, by defining an operation monadically, we can hide underlying machinery in a way that allows new features to be incorporated into the monad transparently. Wadler's paper~\cite{wadler:mffp} is an excellent example of how monads can be used to construct modular programs. We will start with a monad taken directly from this paper, the state monad, and then build a more complex monad with a similar definition. Briefly, a state monad built around a state type @S@ looks like this: \bprog @ data SM a = SM (S -> (a,S)) -- The monadic type instance Monad SM where -- defines state propagation SM c1 >>= fc2 = SM (\s0 -> let (r,s1) = c1 s0 SM c2 = fc2 r in c2 s1) return k = SM (\s -> (k,s)) -- extracts the state from the monad readSM :: SM S readSM = SM (\s -> (s,s)) -- updates the state of the monad updateSM :: (S -> S) -> SM () -- alters the state updateSM f = SM (\s -> ((), f s)) -- run a computation in the SM monad runSM :: S -> SM a -> (a,S) runSM s0 (SM c) = c s0 @ \eprog This example defines a new type, @SM@, to be a computation that implicitly carries a type @S@. That is, a computation of type @SM t@ defines a value of type @t@ while also interacting with (reading and writing) the state of type @S@. The definition of @SM@ is simple: it consists of functions that take a state and produce two results: a returned value (of any type) and an updated state. We can't use a type synonym here: we need a type name like @SM@ that can be used in instance declarations. The @newtype@ declaration is often used here instead of @data@. This instance declaration defines the `plumbing' of the monad: how to sequence two computations and the definition of an empty computation. Sequencing (the @>>=@ operator) defines a computation (denoted by the constructor @SM@) that passes an initial state, @s0@, into @c1@, then passes the value coming out of this computation, @r@, to the function that returns the second computation, @c2@. Finally, the state coming out of @c1@ is passed into @c2@ and the overall result is the result of @c2@. The definition of @return@ is easier: @return@ doesn't change the state at all; it only serves to bring a value into the monad. While @>>=@ and @return@ are the basic monadic sequencing operations, we also need some {\em monadic primitives}. A monadic primitive is simply an operation that uses the insides of the monad abstraction and taps into the `wheels and gears' that make the monad work. For example, in the @IO@ monad, operators such as @putChar@ are primitive since they deal with the inner workings of the @IO@ monad. Similarly, our state monad uses two primitives: @readSM@ and @updateSM@. Note that these depend on the inner structure of the monad - a change to the definition of the @SM@ type would require a change to these primitives. The definition of @readSM@ and @updateSM@ are simple: @readSM@ brings the state out of the monad for observation while @updateSM@ allows the user to alter the state in the monad. (We could also have used @writeSM@ as a primitive but update is often a more natural way of dealing with state). Finally, we need a function that runs computations in the monad, @runSM@. This takes an initial state and a computation and yields both the returned value of the computation and the final state. Looking at the bigger picture, what we are trying to do is define an overall computation as a series of steps (functions with type @SM a@), sequenced using @>>=@ and @return@. These steps may interact with the state (via @readSM@ or @updateSM@) or may ignore the state. However, the use (or non-use) of the state is hidden: we don't invoke or sequence our computations differently depending on whether or not they use @S@. Rather than present any examples using this simple state monad, we proceed on to a more complex example that includes the state monad. We define a small {\em embedded language} of resource-using calculations. That is, we build a special purpose language implemented as a set of Haskell types and functions. Such languages use the basic tools of Haskell, functions and types, to build a library of operations and types specifically tailored to a domain of interest. In this example, consider a computation that requires some sort of resource. If the resource is available, computation proceeds; when the resource is unavailable, the computation suspends. We use the type @R@ to denote a computation using resources controlled by our monad. The definition of @R@ is as follows: \bprog @ data R a = R (Resource -> (Resource, Either a (R a))) @ \eprog Each computation is a function from available resources to remaining resources, coupled with either a result, of type @a@, or a suspended computation, of type @R a@, capturing the work done up to the point where resources were exhausted. The @Monad@ instance for @R@ is as follows: \bprog @ instance Monad R where R c1 >>= fc2 = R (\r -> case c1 r of (r', Left v) -> let R c2 = fc2 v in c2 r' (r', Right pc1) -> (r', Right (pc1 >>= fc2))) return v = R (\r -> (r, (Left v))) @ \eprog The @Resource@ type is used in the same manner as the state in the state monad. This definition reads as follows: to combine two `resourceful' computations, @c1@ and @fc2@ (a function producing @c2@), pass the initial resources into @c1@. The result will be either \begin{itemize} \item a value, @v@, and remaining resources, which are used to determine the next computation (the call @fc2 v@), or \item a suspended computation, @pc1@, and resources remaining at the point of suspension. \end{itemize} The suspension must take the second computation into consideration: @pc1@ suspends only the first computation, @c1@, so we must bind @c2@ to this to produce a suspension of the overall computation. The definition of @return@ leaves the resources unchanged while moving @v@ into the monad. This instance declaration defines the basic structure of the monad but does not determine how resources are used. This monad could be used to control many types of resource or implement many different types of resource usage policies. We will demonstrate a very simple definition of resources as an example: we choose @Resource@ to be an @Integer@, representing available computation steps: \bprog @ type Resource = Integer @ \eprog This function takes a step unless no steps are available: \bprog @ step :: a -> R a step v = c where c = R (\r -> if r /= 0 then (r-1, Left v) else (r, Right c)) @ \eprog The @Left@ and @Right@ constructors are part of the @Either@ type. This function continues computation in @R@ by returning @v@ so long as there is at least one computational step resource available. If no steps are available, the @step@ function suspends the current computation (this suspension is captured in @c@) and passes this suspended computation back into the monad. So far, we have the tools to define a sequence of ``resourceful'' computations (the monad) and we can express a form of resource usage using @step@. Finally, we need to address how computations in this monad are expressed. Consider an increment function in our monad: \bprog @ inc :: R Integer -> R Integer inc i = do iValue <- i step (iValue+1) @ \eprog This defines increment as a single step of computation. The @<-@ is necessary to pull the argument value out of the monad; the type of @iValue@ is @Integer@ instead of @R Integer@. This definition isn't particularly satisfying, though, compared to the standard definition of the increment function. Can we instead ``dress up'' existing operations like @+@ so that they work in our monadic world? We'll start with a set of {\tt lifting} functions. These bring existing functionality into the monad. Consider the definition of @lift1@ (this is slightly different from the @liftM1@ found in the @Monad@ library): \bprog @ lift1 :: (a -> b) -> (R a -> R b) lift1 f = \ra1 -> do a1 <- ra1 step (f a1) @ \eprog This takes a function of a single argument, @f@, and creates a function in @R@ that executes the lifted function in a single step. Using @lift1@, @inc@ becomes \bprog @ inc :: R Integer -> R Integer inc i = lift1 (i+1) @ \eprog This is better but still not ideal. First, we add @lift2@: \bprog @ lift2 :: (a -> b -> c) -> (R a -> R b -> R c) lift2 f = \ra1 ra2 -> do a1 <- ra1 a2 <- ra2 step (f a1 a2) @ \eprog Notice that this function explicitly sets the order of evaluation in the lifted function: the computation yielding @a1@ occurs before the computation for @a2@. Using @lift2@, we can create a new version of @==@ in the @R@ monad: \bprog @ (==*) :: Ord a => R a -> R a -> R Bool (==*) = lift2 (==) @ \eprog We had to use a slightly different name for this new function since @==@ is already taken but in some cases we can use the same name for the lifted and unlifted function. This instance declaration allows all of the operators in @Num@ to be used in @R@: \bprog @ instance Num a => Num (R a) where (+) = lift2 (+) (-) = lift2 (-) negate = lift1 negate (*) = lift2 (*) abs = lift1 abs fromInteger = return . fromInteger @ \eprog The @fromInteger@ function is applied implicitly to all integer constants in a Haskell program (see Section \ref{tut-num-constants}); this definition allows integer constants to have the type @R Integer@. We can now, finally, write increment in a completely natural style: \bprog @ inc :: R Integer -> R Integer inc x = x + 1 @ \eprog Note that we cannot lift the @Eq@ class in the same manner as the @Num@ class: the signature of @==*@ is not compatible with allowable overloadings of @==@ since the result of @==*@ is @R Bool@ instead of @Bool@. To express interesting computations in @R@ we will need a conditional. Since we can't use @if@ (it requires that the test be of type @Bool@ instead of @R Bool@), we name the function @ifR@: \bprog @ ifR :: R Bool -> R a -> R a -> R a ifR tst thn els = do t <- tst if t then thn else els @ \eprog Now we're ready for a larger program in the @R@ monad: \bprog @ fact :: R Integer -> R Integer fact x = ifR (x ==* 0) 1 (x * fact (x-1)) @ \eprog Now this isn't quite the same as an ordinary factorial function but still quite readable. The idea of providing new definitions for existing operations like @+@ or @if@ is an essential part of creating an embedded language in Haskell. Monads are particularly useful for encapsulating the semantics of these embedded languages in a clean and modular way. We're now ready to actually run some programs. This function runs a program in @M@ given a maximum number of computation steps: \bprog @ run :: Resource -> R a -> Maybe a run s (R p) = case (p s) of (_, Left v) -> Just v _ -> Nothing @ \eprog We use the @Maybe@ type to deal with the possibility of the computation not finishing in the allotted number of steps. We can now compute \[\ba{lcl} @run 10 (fact 2)@ \ \ \ &\red&\ \ \ @Just 2@\\ @run 10 (fact 20)@ \ \ \ &\red&\ \ \ @Nothing@\\ \ea\] Finally, we can add some more interesting functionality to this monad. Consider the following function: \bprog @ (|||) :: R a -> R a -> R a @ \eprog This runs two computations in parallel, returning the value of the first one to complete. One possible definition of this function is: \bprog @ c1 ||| c2 = oneStep c1 (\c1' -> c2 ||| c1') where oneStep :: R a -> (R a -> R a) -> R a oneStep (R c1) f = R (\r -> case c1 1 of (r', Left v) -> (r+r'-1, Left v) (r', Right c1') -> -- r' must be 0 let R next = f c1' in next (r+r'-1)) @ \eprog This takes a step in @c1@, returning its value of @c1@ complete or, if @c1@ returns a suspended computation (@c1'@), it evaluates @c2 ||| c1'@. The @oneStep@ function takes a single step in its argument, either returning an evaluated value or passing the remainder of the computation into @f@. The definition of @oneStep@ is simple: it gives @c1@ a 1 as its resource argument. If a final value is reached, this is returned, adjusting the returned step count (it is possible that a computation might return after taking no steps so the returned resource count isn't necessarily 0). If the computation suspends, a patched up resource count is passed to the final continuation. We can now evaluate expressions like @run 100 (fact (-1) ||| (fact 3))@ without looping since the two calculations are interleaved. (Our definition of @fact@ loops for @-1@). Many variations are possible on this basic structure. For example, we could extend the state to include a trace of the computation steps. We could also embed this monad inside the standard @IO@ monad, allowing computations in @M@ to interact with the outside world. While this example is perhaps more advanced than others in this tutorial, it serves to illustrate the power of monads as a tool for defining the basic semantics of a system. We also present this example as a model of a small {\em Domain Specific Language}, something Haskell is particularly good at defining. Many other DSLs have been developed in Haskell; see {\tt haskell.org} for many more examples. Of particular interest are Fran, a language of reactive animations, and Haskore, a language of computer music. %**~footer haskell-98-tutorial-sources/moretypes.verb0100644000106400000620000002424007065467732017333 0ustar jcpftp%**A Gentle Introduction to Haskell: Types, Again %**~header \section{Types, Again} Here we examine some of the more advanced aspects of type declarations. \subsection{The Newtype Declaration} A common programming practice is to define a type whose representation is identical to an existing one but which has a separate identity in the type system. In Haskell, the @newtype@ declaration creates a new type from an existing one. For example, natural numbers can be represented by the type @Integer@ using the following declaration: \bprog @ newtype Natural = MakeNatural Integer @ \eprog This creates an entirely new type, @Natural@, whose only constructor contains a single @Integer@. The constructor @MakeNatural@ converts between an @Natural@ and an @Integer@: \bprog @ toNatural :: Integer -> Natural toNatural x | x < 0 = error "Can't create negative naturals!" | otherwise = MakeNatural x fromNatural :: Natural -> Integer fromNatural (MakeNatural i) = i @ \eprog The following instance declaration admits @Natural@ to the @Num@ class: \bprog @ instance Num Natural where fromInteger = toNatural x + y = toNatural (fromNatural x + fromNatural y) x - y = let r = fromNatural x - fromNatural y in if r < 0 then error "Unnatural subtraction" else toNatural r x * y = toNatural (fromNatural x * fromNatural y) @ \eprog Without this declaration, @Natural@ would not be in @Num@. Instances declared for the old type do not carry over to the new one. Indeed, the whole purpose of this type is to introduce a different @Num@ instance. This would not be possible if @Natural@ were defined as a type synonym of @Integer@. All of this works using a @data@ declaration instead of a @newtype@ declaration. However, the @data@ declaration incurs extra overhead in the representation of @Natural@ values. The use of @newtype@ avoids the extra level of indirection (caused by laziness) that the @data@ declaration would introduce. See section \ref{datatype-renaming} of the report for a more discussion of the relation between @newtype@, @data@, and @type@ declarations. \syn{Except for the keyword, the @newtype@ declaration uses the same syntax as a @data@ declaration with a single constructor containing a single field. This is appropriate since types defined using @newtype@ are nearly identical to those created by an ordinary @data@ declaration.} \subsection{Field Labels} The fields within a Haskell data type can be accessed either positionally or by name using "field labels". Consider a data type for a two-dimensional point: \bprog @ data Point = Pt Float Float @ \eprog The two components of a @Point@ are the first and second arguments to the constructor @Pt@. A function such as \bprog @ pointx :: Point -> Float pointx (Pt x _) = x @ \eprog may be used to refer to the first component of a point in a more descriptive way, but, for large structures, it becomes tedious to create such functions by hand. Constructors in a @data@ declaration may be declared with associated "field names", enclosed in braces. These field names identify the components of constructor by name rather than by position. This is an alternative way to define @Point@: \bprog @ data Point = Pt {pointx, pointy :: Float} @ \eprog This data type is identical to the earlier definition of @Point@. The constructor @Pt@ is the same in both cases. However, this declaration also defines two field names, @pointx@ and @pointy@. These field names can be used as "selector functions" to extract a component from a structure. In this example, the selectors are: \bprog @ pointx :: Point -> Float pointy :: Point -> Float @ \eprog This is a function using these selectors: \bprog @ absPoint :: Point -> Float absPoint p = sqrt (pointx p * pointx p + pointy p * pointy p) @ \eprog Field labels can also be used to construct new values. The expression @Pt {pointx=1, pointy=2}@ is identical to @Pt 1 2@. The use of field names in the declaration of a data constructor does not preclude the positional style of field access; both @Pt {pointx=1, pointy=2}@ and @Pt 1 2@ are allowed. When constructing a value using field names, some fields may be omitted; these absent fields are undefined. Pattern matching using field names uses a similar syntax for the constructor @Pt@: \bprog @ absPoint (Pt {pointx = x, pointy = y}) = sqrt (x*x + y*y) @ \eprog An update function uses field values in an existing structure to fill in components of a new structure. If @p@ is a @Point@, then @p {pointx=2}@ is a point with the same @pointy@ as @p@ but with @pointx@ replaced by @2@. This is not a destructive update: the update function merely creates a new copy of the object, filling in the specified fields with new values. \syn{The braces used in conjunction with field labels are somewhat special: Haskell syntax usually allows braces to be omitted using the "layout rule" (described in Section \ref{tut-layout}). However, the braces associated with field names must be explicit.} %Within the braces used to name the fields of a structure, {\em %punning}---using the same word in two different ways---can be used to %abbreviate bindings which associate a field name with a local variable %of the same name. That is, @{pointx}@ abbreviates @{pointx = pointx}@ %in a field list. Thus, the @abs@ function could also be written %\bprog % %abs (Pt {pointx, pointy}) = sqrt (pointx*pointx + pointy*pointy) % %\eprog Field names are not restricted to types with a single constructor (commonly called `record' types). In a type with multiple constructors, selection or update operations using field names may fail at runtime. This is similar to the behavior of the @head@ function when applied to an empty list. Field labels share the top level namespace with ordinary variables and class methods. A field name cannot be used in more than one data type in scope. However, within a data type, the same field name can be used in more than one of the constructors so long as it has the same typing in all cases. For example, in this data type \bprog @ data T = C1 {f :: Int, g :: Float} | C2 {f :: Int, h :: Bool} @ \eprog the field name @f@ applies to both constructors in @T@. Thus if @x@ is of type @T@, then @x {f=5}@ will work for values created by either of the constructors in @T@. Field names does not change the basic nature of an algebraic data type; they are simply a convenient syntax for accessing the components of a data structure by name rather than by position. They make constructors with many components more manageable since fields can be added or removed without changing every reference to the constructor. For full details of field labels and their semantics, see Section~\see{field-labels}. \subsection{Strict Data Constructors} \label{tut-strict-flag} Data structures in Haskell are generally "lazy": the components are not evaluated until needed. This permits structures that contain elements which, if evaluated, would lead to an error or fail to terminate. Lazy data structures enhance the expressiveness of Haskell and are an essential aspect of the Haskell programming style. Internally, each field of a lazy data object is wrapped up in a structure commonly referred to as a "thunk" that encapsulates the computation defining the field value. This thunk is not entered until the value is needed; thunks which contain errors ("\bot") do not affect other elements of a data structure. For example, the tuple @('a',@"\bot"@)@ is a perfectly legal Haskell value. The @'a'@ may be used without disturbing the other component of the tuple. Most programming languages are "strict" instead of lazy: that is, all components of a data structure are reduced to values before being placed in the structure. There are a number of overheads associated with thunks: they take time to construct and evaluate, they occupy space in the heap, and they cause the garbage collector to retain other structures needed for the evaluation of the thunk. To avoid these overheads, {\em strictness flags} in @data@ declarations allow specific fields of a constructor to be evaluated immediately, selectively suppressing laziness. A field marked by "@!@" in a @data@ declaration is evaluated when the structure is created instead of delayed in a thunk. There are a number of situations where it may be appropriate to use strictness flags: \begin{itemize} \item Structure components that are sure to be evaluated at some point during program execution. \item Structure components that are simple to evaluate and never cause errors. \item Types in which partially undefined values are not meaningful. \end{itemize} For example, the complex number library defines the @Complex@ type as: \bprog @ data RealFloat a => Complex a = !a :+ !a @ \eprog \syn{note the infix definition of the constructor @:+@.} This definition marks the two components, the real and imaginary parts, of the complex number as being strict. This is a more compact representation of complex numbers but this comes at the expense of making a complex number with an undefined component, @1 :+ @ "\bot" for example, totally undefined ("\bot"). As there is no real need for partially defined complex numbers, it makes sense to use strictness flags to achieve a more efficient representation. Strictness flags may be used to address memory leaks: structures retained by the garbage collector but no longer necessary for computation. The strictness flag, @!@, can only appear in @data@ declarations. It cannot be used in other type signatures or in any other type definitions. There is no corresponding way to mark function arguments as being strict, although the same effect can be obtained using the @seq@ or @!$@ functions. See ~\see{strictness-flags} for further details. It is difficult to present exact guidelines for the use of strictness flags. They should be used with caution: laziness is one of the fundamental properties of Haskell and adding strictness flags may lead to hard to find infinite loops or have other unexpected consequences. %**~footer haskell-98-tutorial-sources/numbers.verb0100644000106400000620000002370307065471023016746 0ustar jcpftp%**A Gentle Introduction to Haskell: Numbers %**~header \section{Numbers} Haskell provides a rich collection of numeric types, based on those of Scheme~\cite{RRRRS}, which in turn are based on Common Lisp~\cite{steele:common-lisp}. (Those languages, however, are dynamically typed.) The standard types include fixed- and arbitrary-precision integers, ratios (rational numbers) formed from each integer type, and single- and double-precision real and complex floating-point. We outline here the basic characteristics of the numeric type class structure and refer the reader to \see{numbers} for details. \subsection{Numeric Class Structure} The numeric type classes (class @Num@ and those that lie below it) account for many of the standard Haskell classes. We also note that @Num@ is a subclass of @Eq@, but not of @Ord@; this is because the order predicates do not apply to complex numbers. The subclass @Real@ of @Num@, however, is a subclass of @Ord@ as well. The @Num@ class provides several basic operations common to all numeric types; these include, among others, addition, subtraction, negation, multiplication, and absolute value: \bprog @ (+), (-), (*) :: (Num a) => a -> a -> a negate, abs :: (Num a) => a -> a @ \eprog \syn{@negate@ is the function applied by Haskell's only prefix operator, minus; we can't call it @(-)@, because that is the subtraction function, so this name is provided instead. For example, @-x*y@ is equivalent to @negate (x*y)@. (Prefix minus has the same syntactic precedence as infix minus, which, of course, is lower than that of multiplication.)} Note that @Num@ does {\em not} provide a division operator; two different kinds of division operators are provided in two non-overlapping subclasses of @Num@: The class @Integral@ provides whole-number division and remainder operations. The standard instances of @Integral@ are @Integer@ (unbounded or mathematical integers, also known as ``bignums'') and @Int@ (bounded, machine integers, with a range equivalent to at least 29-bit signed binary). A particular Haskell implementation might provide other integral types in addition to these. Note that @Integral@ is a subclass of @Real@, rather than of @Num@ directly; this means that there is no attempt to provide Gaussian integers. All other numeric types fall in the class @Fractional@, which provides the ordinary division operator @(/)@. The further subclass @Floating@ contains trigonometric, logarithmic, and exponential functions. The @RealFrac@ subclass of @Fractional@ and @Real@ provides a function @properFraction@, which decomposes a number into its whole and fractional parts, and a collection of functions that round to integral values by differing rules: \bprog @ properFraction :: (Fractional a, Integral b) => a -> (b,a) truncate, round, floor, ceiling: :: (Fractional a, Integral b) => a -> b @ \eprog The @RealFloat@ subclass of @Floating@ and @RealFrac@ provides some specialized functions for efficient access to the components of a floating-point number, the {\em exponent} and {\em significand}. The standard types @Float@ and @Double@ fall in class @RealFloat@. \subsection{Constructed Numbers} Of the standard numeric types, @Int@, @Integer@, @Float@, and @Double@ are primitive. The others are made from these by type constructors. @Complex@ (found in the library @Complex@) is a type constructor that makes a complex type in class @Floating@ from a @RealFloat@ type: \bprog @ data (RealFloat a) => Complex a = !a :+ !a deriving (Eq, Text) @ \eprog The @!@ symbols are strictness flags; these were discussed in Section~ \ref{tut-strict-flag}. Notice the context @RealFloat a@, which restricts the argument type; thus, the standard complex types are @Complex Float@ and @Complex Double@. We can also see from the @data@ declaration that a complex number is written "x" @:+@ "y"; the arguments are the cartesian real and imaginary parts, respectively. Since @:+@ is a data constructor, we can use it in pattern matching: \bprog @ conjugate :: (RealFloat a) => Complex a -> Complex a conjugate (x:+y) = x :+ (-y) @ \eprog Similarly, the type constructor @Ratio@ (found in the @Rational@ library) makes a rational type in class @RealFrac@ from an instance of @Integral@. (@Rational@ is a type synonym for @Ratio Integer@.) @Ratio@, however, is an abstract type constructor. Instead of a data constructor like @:+@, rationals use the `@%@' function to form a ratio from two integers. Instead of pattern matching, component extraction functions are provided: \bprog @ (%) :: (Integral a) => a -> a -> Ratio a numerator, denominator :: (Integral a) => Ratio a -> a @ \eprog Why the difference? Complex numbers in cartesian form are unique---there are no nontrivial identities involving @:+@. On the other hand, ratios are not unique, but have a canonical (reduced) form that the implementation of the abstract data type must maintain; it is not necessarily the case, for instance, that @numerator (x%y)@ is equal to @x@, although the real part of @x:+y@ is always @x@. \subsection{Numeric Coercions and Overloaded Literals} \label{tut-num-constants} The Standard Prelude and libraries provide several overloaded functions that serve as explicit coercions: \bprog @ fromInteger :: (Num a) => Integer -> a fromRational :: (Fractional a) => Rational -> a toInteger :: (Integral a) => a -> Integer toRational :: (RealFrac a) => a -> Rational fromIntegral :: (Integral a, Num b) => a -> b fromRealFrac :: (RealFrac a, Fractional b) => a -> b fromIntegral = fromInteger . toInteger fromRealFrac = fromRational . toRational @ \eprog Two of these are implicitly used to provide overloaded numeric literals: An integer numeral (without a decimal point) is actually equivalent to an application of @fromInteger@ to the value of the numeral as an @Integer@. Similarly, a floating numeral (with a decimal point) is regarded as an application of @fromRational@ to the value of the numeral as a @Rational@. Thus, @7@ has the type @(Num a) => a@, and @7.3@ has the type @(Fractional a) => a@. This means that we can use numeric literals in generic numeric functions, for example: \bprog @ halve :: (Fractional a) => a -> a halve x = x * 0.5 @ \eprog This rather indirect way of overloading numerals has the additional advantage that the method of interpreting a numeral as a number of a given type can be specified in an @Integral@ or @Fractional@ instance declaration (since @fromInteger@ and @fromRational@ are operators of those classes, respectively). For example, the @Num@ instance of @(RealFloat a) => Complex a@ contains this method: \bprog @ fromInteger x = fromInteger x :+ 0 @ \eprog This says that a @Complex@ instance of @fromInteger@ is defined to produce a complex number whose real part is supplied by an appropriate @RealFloat@ instance of @fromInteger@. In this manner, even user-defined numeric types (say, quaternions) can make use of overloaded numerals. As another example, recall our first definition of @inc@ from Section \ref{tut-values-etc}: \bprog @ inc :: Integer -> Integer inc n = n+1 @ \eprog Ignoring the type signature, the most general type of @inc@ is @(Num a) => a->a@. The explicit type signature is legal, however, since it is {\em more specific} than the principal type (a more general type signature would cause a static error). The type signature has the effect of restricting @inc@'s type, and in this case would cause something like @inc (1::Float)@ to be ill-typed. \subsection{Default Numeric Types} Consider the following function definition: \bprog @ rms :: (Floating a) => a -> a -> a rms x y = sqrt ((x^2 + y^2) * 0.5) @ \eprog The exponentiation function @(^)@ (one of three different standard exponentiation operators with different typings, see \S{6.8.5}) has the type @(Num a, Integral b) => a -> b -> a@, and since @2@ has the type @(Num a) => a@, the type of @x^2@ is @(Num a, Integral b) => a@. This is a problem; there is no way to resolve the overloading associated with the type variable @b@, since it is in the context, but has otherwise vanished from the type expression. Essentially, the programmer has specified that @x@ should be squared, but has not specified whether it should be squared with an @Int@ or an @Integer@ value of two. Of course, we can fix this: \bprog @ rms x y = sqrt ((x ^ (2::Integer) + y ^ (2::Integer)) * 0.5) @ \eprog It's obvious that this sort of thing will soon grow tiresome, however. In fact, this kind of overloading ambiguity is not restricted to numbers: \bprog @ show (read "xyz") @ \eprog As what type is the string supposed to be read? This is more serious than the exponentiation ambiguity, because there, any @Integral@ instance will do, whereas here, very different behavior can be expected depending on what instance of @Text@ is used to resolve the ambiguity. Because of the difference between the numeric and general cases of the overloading ambiguity problem, Haskell provides a solution that is restricted to numbers: Each module may contain a {\em default declaration,} consisting of the keyword @default@ followed by a parenthesized, comma-separated list of numeric monotypes (types with no variables). When an ambiguous type variable is discovered (such as @b@, above), if at least one of its classes is numeric and all of its classes are standard, the default list is consulted, and the first type from the list that will satisfy the context of the type variable is used. For example, if the default declaration @default (Int, Float)@ is in effect, the ambiguous exponent above will be resolved as type @Int@. (See \see{default-decls} for more details.) The ``default default'' is @(Integer, Double)@, but @(Integer, Rational, Double)@ may also be appropriate. Very cautious programmers may prefer @default ()@, which provides no defaults. %**~footer haskell-98-tutorial-sources/patterns.verb0100644000106400000620000004237207065440346017142 0ustar jcpftp%**A Gentle Introduction to Haskell: Patterns %**~header \section{Case Expressions and Pattern Matching} \label{tut-pattern-matching} Earlier we gave several examples of pattern matching in defining functions---for example @length@ and @fringe@. In this section we will look at the pattern-matching process in greater detail (\see{pattern-matching}).\footnote{Pattern matching in Haskell is different from that found in logic programming languages such as Prolog; in particular, it can be viewed as ``one-way'' matching, whereas Prolog allows ``two-way'' matching (via unification), along with implicit backtracking in its evaluation mechanism.} Patterns are not ``first-class;'' there is only a fixed set of different kinds of patterns. We have already seen several examples of {\em data constructor} patterns; both @length@ and @fringe@ defined earlier use such patterns, the former on the constructors of a ``built-in'' type (lists), the latter on a user-defined type (@Tree@). Indeed, matching is permitted using the constructors of any type, user-defined or not. This includes tuples, strings, numbers, characters, etc. For example, here's a contrived function that matches against a tuple of ``constants:'' \bprog @ contrived :: ([a], Char, (Int, Float), String, Bool) -> Bool contrived ([], 'b', (1, 2.0), "hi", True) = False @ \eprog This example also demonstrates that {\em nesting} of patterns is permitted (to arbitrary depth). Technically speaking, {\em formal parameters}\footnote{The Report calls these {\em variables}.} are also patterns---it's just that they {\em never fail to match a value}. As a ``side effect'' of the successful match, the formal parameter is bound to the value it is being matched against. For this reason patterns in any one equation are not allowed to have more than one occurrence of the same formal parameter (a property called {\em linearity} \see{pattern-matching}, \see{lambda-abstractions}, \see{function-bindings}). Patterns such as formal parameters that never fail to match are said to be {\em irrefutable}, in contrast to {\em refutable} patterns which may fail to match. The pattern used in the @contrived@ example above is refutable. There are three other kinds of irrefutable patterns, two of which we will introduce now (the other we will delay until Section \ref{tut-lazy-patterns}). \paragraph*{As-patterns.} Sometimes it is convenient to name a pattern for use on the right-hand side of an equation. For example, a function that duplicates the first element in a list might be written as: \bprog @ f (x:xs) = x:x:xs @ \eprog (Recall that ``@:@'' associates to the right.) Note that @x:xs@ appears both as a pattern on the left-hand side, and an expression on the right-hand side. To improve readability, we might prefer to write @x:xs@ just once, which we can achieve using an {\em as-pattern} as follows:\footnote{Another advantage to doing this is that a naive implementation might completely reconstruct @x:xs@ rather than re-use the value being matched against.} \bprog @ f s@@(x:xs) = x:s @ \eprog Technically speaking, as-patterns always result in a successful match, although the sub-pattern (in this case @x:xs@) could, of course, fail. \paragraph*{Wild-cards.} Another common situation is matching against a value we really care nothing about. For example, the functions @head@ and @tail@ defined in Section \ref{tut-polymorphism} can be rewritten as: \bprog @ head (x:_) = x tail (_:xs) = xs @ \eprog in which we have ``advertised'' the fact that we don't care what a certain part of the input is. Each wild-card independently matches anything, but in contrast to a formal parameter, each binds nothing; for this reason more than one is allowed in an equation. \subsection{Pattern-Matching Semantics} \label{tut-matching-semantics} So far we have discussed how individual patterns are matched, how some are refutable, some are irrefutable, etc. But what drives the overall process? In what order are the matches attempted? What if none succeeds? This section addresses these questions. Pattern matching can either {\em fail}, {\em succeed} or {\em diverge}. A successful match binds the formal parameters in the pattern. Divergence occurs when a value needed by the pattern contains an error ($\bot$). The matching process itself occurs ``top-down, left-to-right.'' Failure of a pattern anywhere in one equation results in failure of the whole equation, and the next equation is then tried. If all equations fail, the value of the function application is $\bot$, and results in a run-time error. For example, if @[1,2]@ is matched against @[0,bot]@, then @1@ fails to match @0@, so the result is a failed match. (Recall that @bot@, defined earlier, is a variable bound to $\bot$.) But if @[1,2]@ is matched against @[bot,0]@, then matching @1@ against @bot@ causes divergence (i.e.~$\bot$). The other twist to this set of rules is that top-level patterns may also have a boolean {\em guard}, as in this definition of a function that forms an abstract version of a number's sign: \bprog @ sign x | x > 0 = 1 | x == 0 = 0 | x < 0 = -1 @ \eprog Note that a sequence of guards may be provided for the same pattern; as with patterns, they are evaluated top-down, and the first that evaluates to @True@ results in a successful match. \subsection{An Example} The pattern-matching rules can have subtle effects on the meaning of functions. For example, consider this definition of @take@: \bprog @ take 0 _ = [] take _ [] = [] take n (x:xs) = x : take (n-1) xs @ \eprog and this slightly different version (the first 2 equations have been reversed): \bprog @ take1 _ [] = [] take1 0 _ = [] take1 n (x:xs) = x : take1 (n-1) xs @ \eprog Now note the following: \[\ba{lcl} @take 0 bot@ &\ \ \ \red\ \ \ & @[]@ \\ @take1 0 bot@ &\ \ \ \red\ \ \ & \bot \\[.1in] @take bot []@ &\ \ \ \red\ \ \ & \bot \\ @take1 bot []@ &\ \ \ \red\ \ \ & @[]@ \ea\] We see that @take@ is ``more defined'' with respect to its second argument, whereas @take1@ is more defined with respect to its first. It is difficult to say in this case which definition is better. Just remember that in certain applications, it may make a difference. (The Standard Prelude includes a definition corresponding to @take@.) \subsection{Case Expressions} \label{tut-case} Pattern matching provides a way to ``dispatch control'' based on structural properties of a value. In many circumstances we don't wish to define a {\em function} every time we need to do this, but so far we have only shown how to do pattern matching in function definitions. Haskell's {\em case expression} provides a way to solve this problem. Indeed, the meaning of pattern matching in function definitions is specified in the Report in terms of case expressions, which are considered more primitive. In particular, a function definition of the form: \[\ba{l} "@f@ p_{11} ... p_{1k} @=@ e_{1}" \\ "..." \\ "@f@ p_{n1} ... p_{nk} @=@ e_{n}" \ea\] where each "p_{ij}" is a pattern, is semantically equivalent to: \[ "@f x1 x2@ ... @xk = case (x1, @...@, xk) of@" \ba[t]{l} "@(@p_{11}, ..., p_{1k}@) ->@ e_{1}" \\ "..." \\ "@(@p_{n1}, ..., p_{nk}@) ->@ e_{n}" \ea \] where the @xi@ are new identifiers. (For a more general translation that includes guards, see \see{function-bindings}.) For example, the definition of @take@ given earlier is equivalent to: \bprog @ take m ys = case (m,ys) of (0,_) -> [] (_,[]) -> [] (n,x:xs) -> x : take (n-1) xs @ \eprog A point not made earlier is that, for type correctness, the types of the right-hand sides of a case expression or set of equations comprising a function definition must all be the same; more precisely, they must all share a common principal type. The pattern-matching rules for case expressions are the same as we have given for function definitions, so there is really nothing new to learn here, other than to note the convenience that case expressions offer. Indeed, there's one use of a case expression that is so common that it has special syntax: the {\em conditional expression}. In Haskell, conditional expressions have the familiar form: \[ @if@\ e_1\ @then@\ e_2\ @else@\ e_3 \] which is really short-hand for: \[\ba{ll} @case@\ e_1\ @of@ & @True ->@\ e_2\\ & @False ->@\ e_3 \ea\] {}From this expansion it should be clear that $e_1$ must have type @Bool@, and $e_2$ and $e_3$ must have the same (but otherwise arbitrary) type. In other words, @if@-@then@-@else@ when viewed as a function has type @Bool->a->a->a@. \subsection{Lazy Patterns} \label{tut-lazy-patterns} There is one other kind of pattern allowed in Haskell. It is called a {\em lazy pattern}, and has the form @~@$pat$. Lazy patterns are {\em irrefutable}: matching a value $v$ against @~@$pat$ always succeeds, regardless of $pat$. Operationally speaking, if an identifier in $pat$ is later ``used'' on the right-hand-side, it will be bound to that portion of the value that would result if $v$ were to successfully match $pat$, and $\bot$ otherwise. Lazy patterns are useful in contexts where infinite data structures are being defined recursively. For example, infinite lists are an excellent vehicle for writing {\em simulation} programs, and in this context the infinite lists are often called {\em streams}. Consider the simple case of simulating the interactions between a server process @server@ and a client process @client@, where @client@ sends a sequence of {\em requests} to @server@, and @server@ replies to each request with some kind of {\em response}. This situation is shown pictorially in Figure \ref{tut-client-fig}. (Note that @client@ also takes an initial message as argument.) %**
Client Server Example %**

Figure 2

Using streams to simulate the message sequences, the Haskell code corresponding to this diagram is: \bprog @ reqs = client init resps resps = server reqs @ \eprog These recursive equations are a direct lexical transliteration of the diagram. %*ignore \begin{figure} \begin{center} \mbox{ \epsfbox{fig2.eps}} \end{center} \caption{Client-Server Simulation} \label{tut-client-fig} \end{figure} %*endignore Let us further assume that the structure of the server and client look something like this: \bprog @ client init (resp:resps) = init : client (next resp) resps server (req:reqs) = process req : server reqs @ \eprog where we assume that @next@ is a function that, given a response from the server, determines the next request, and @process@ is a function that processes a request from the client, returning an appropriate response. Unfortunately, this program has a serious problem: it will not produce any output! The problem is that @client@, as used in the recursive setting of @reqs@ and @resps@, attempts a match on the response list before it has submitted its first request! In other words, the pattern matching is being done ``too early.'' One way to fix this is to redefine @client@ as follows: \bprog @ client init resps = init : client (next (head resps)) (tail resps) @ \eprog Although workable, this solution does not read as well as that given earlier. A better solution is to use a lazy pattern: \bprog @ client init ~(resp:resps) = init : client (next resp) resps @ \eprog Because lazy patterns are irrefutable, the match will immediately succeed, allowing the initial request to be ``submitted'', in turn allowing the first response to be generated; the engine is now ``primed'', and the recursion takes care of the rest. As an example of this program in action, if we define: \bprog @ init = 0 next resp = resp process req = req+1 @ \eprog then we see that: \[ @take 10 reqs@\ \ \ \ \red\ \ \ \ @[0,1,2,3,4,5,6,7,8,9]@ \] As another example of the use of lazy patterns, consider the definition of Fibonacci given earlier: \bprog @ fib = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ] @ \eprog We might try rewriting this using an as-pattern: \bprog @ fib@@(1:tfib) = 1 : 1 : [ a+b | (a,b) <- zip fib tfib ] @ \eprog This version of @fib@ has the (small) advantage of not using @tail@ on the right-hand side, since it is available in ``destructured'' form on the left-hand side as @tfib@. \syn{This kind of equation is called a {\em pattern binding} because it is a top-level equation in which the entire left-hand side is a pattern; i.e.\ both @fib@ and @tfib@ become bound within the scope of the declaration.} Now, using the same reasoning as earlier, we should be led to believe that this program will not generate any output. Curiously, however, it {\em does}, and the reason is simple: in Haskell, pattern bindings are assumed to have an implicit @~@ in front of them, reflecting the most common behavior expected of pattern bindings, and avoiding some anomalous situations which are beyond the scope of this tutorial. Thus we see that lazy patterns play an important role in Haskell, if only implicitly. \subsection{Lexical Scoping and Nested Forms} \label{tut-nesting} It is often desirable to create a nested scope within an expression, for the purpose of creating local bindings not seen elsewhere---i.e. some kind of ``block-structuring'' form. In Haskell there are two ways to achieve this: \paragraph*{Let Expressions.} Haskell's {\em let expressions} are useful whenever a nested set of bindings is required. As a simple example, consider: \bprog @ let y = a*b f x = (x+y)/y in f c + f d @ \eprog The set of bindings created by a @let@ expression is {\em mutually recursive}, and pattern bindings are treated as lazy patterns (i.e. they carry an implicit @~@). The only kind of declarations permitted are {\em type signatures}, {\em function bindings}, and {\em pattern bindings}. \paragraph*{Where Clauses.} Sometimes it is convenient to scope bindings over several guarded equations, which requires a {\em where clause}: \bprog @ f x y | y>z = ... | y==z = ... | yA Gentle Introduction to Haskell: Typing Pitfalls %**~header \section{Typing Pitfalls} This short section give an intuitive description of a few common problems that novices run into using Haskell's type system. \subsection{Let-Bound Polymorphism} Any language using the Hindley-Milner type system has what is called {\em let-bound polymorphism}, because identifiers not bound using a @let@ or @where@ clause (or at the top level of a module) are limited with respect to their polymorphism. In particular, a {\em lambda-bound} function (i.e., one passed as argument to another function) cannot be instantiated in two different ways. For example, this program is illegal: \bprog @ let f g = (g [], g 'a') -- ill-typed expression in f (\x->x) @ \eprog because @g@, bound to a lambda abstraction whose principal type is @a->a@, is used within @f@ in two different ways: once with type @[a]->[a]@, and once with type @Char->Char@. \subsection{Numeric Overloading} It is easy to forget at times that numerals are {\em overloaded,} and {\em not implicitly coerced} to the various numeric types, as in many other languages. More general numeric expressions sometimes cannot be quite so generic. A common numeric typing error is something like the following: \bprog @ average xs = sum xs / length xs -- Wrong! @ \eprog @(/)@ requires fractional arguments, but @length@'s result is an @Int@. The type mismatch must be corrected with an explicit coercion: \bprog @ average :: (Fractional a) => [a] -> a average xs = sum xs / fromIntegral (length xs) @ \eprog \subsection{The Monomorphism Restriction} The Haskell type system contains a restriction related to type classes that is not found in ordinary Hindley-Milner type systems: the {\em monomorphism restriction}. The reason for this restriction is related to a subtle type ambiguity and is explained in full detail in the Report (\see{sect:monomorphism-restriction}). A simpler explanation follows: The monomorphism restriction says that any identifier bound by a pattern binding (which includes bindings to a single identifier), and having no explicit type signature, must be {\em monomorphic}. An identifier is monomorphic if is either not overloaded, or is overloaded but is used in at most one specific overloading and is not exported. Violations of this restriction result in a static type error. The simplest way to avoid the problem is to provide an explicit type signature. Note that {\em any} type signature will do (as long it is type correct). A common violation of the restriction happens with functions defined in a higher-order manner, as in this definition of @sum@ from the Standard Prelude: \bprog @ sum = foldl (+) 0 @ \eprog As is, this would cause a static type error. We can fix the problem by adding the type signature: \bprog @ sum :: (Num a) => [a] -> a @ \eprog Also note that this problem would not have arisen if we had written: \bprog @ sum xs = foldl (+) 0 xs @ \eprog because the restriction only applies to pattern bindings. %**~footer haskell-98-tutorial-sources/stdclasses.verb0100644000106400000620000004172207065470416017451 0ustar jcpftp%**A Gentle Introduction to Haskell: Standard Classes %**~header \section{Standard Haskell Classes} In this section we introduce the predefined standard type classes in Haskell. We have simplified these classes somewhat by omitting some of the less interesting methods in these classes; the Haskell report contains a more complete description. Also, some of the standard classes are part of the standard Haskell libraries; these are described in the Haskell Library Report. \subsection{Equality and Ordered Classes} The classes @Eq@ and @Ord@ have already been discussed. The definition of @Ord@ in the Prelude is somewhat more complex than the simplified version of @Ord@ presented earlier. In particular, note the @compare@ method: \bprog @ data Ordering = EQ | LT | GT compare :: Ord a => a -> a -> Ordering @ \eprog The @compare@ method is sufficient to define all other methods (via defaults) in this class and is the best way to create @Ord@ instances. \subsection{The Enumeration Class} \label{tut-enum-classes} Class @Enum@ has a set of operations that underlie the syntactic sugar of arithmetic sequences; for example, the arithmetic sequence expression @[1,3..]@ stands for @enumFromThen 1 3@ (see \see{arithmetic-sequences} for the formal translation). We can now see that arithmetic sequence expressions can be used to generate lists of any type that is an instance of @Enum@. This includes not only most numeric types, but also @Char@, so that, for instance, @['a'..'z']@ denotes the list of lower-case letters in alphabetical order. Furthermore, user-defined enumerated types like @Color@ can easily be given @Enum@ instance declarations. If so: \[ @[Red .. Violet]@\ \ \ \ \red\ \ \ \ @[Red, Green, Blue, Indigo, Violet]@ \] Note that such a sequence is {\em arithmetic} in the sense that the increment between values is constant, even though the values are not numbers. Most types in @Enum@ can be mapped onto fixed precision integers; for these, the @fromEnum@ and @toEnum@ convert between @Int@ and a type in @Enum@. \subsection{The Read and Show Classes} \label{tut-text-class} The instances of class @Show@ are those types that can be converted to character strings (typically for I/O). The class @Read@ provides operations for parsing character strings to obtain the values they may represent. The simplest function in the class @Show@ is @show@: \bprog @ show :: (Show a) => a -> String @ \eprog Naturally enough, @show@ takes any value of an appropriate type and returns its representation as a character string (list of characters), as in @show (2+2)@, which results in @"4"@. This is fine as far as it goes, but we typically need to produce more complex strings that may have the representations of many values in them, as in \bprog @ "The sum of " ++ show x ++ " and " ++ show y ++ " is " ++ show (x+y) ++ "." @ \eprog and after a while, all that concatenation gets to be a bit inefficient. Specifically, let's consider a function to represent the binary trees of Section \ref{tut-recursive-types} as a string, with suitable markings to show the nesting of subtrees and the separation of left and right branches (provided the element type is representable as a string): \bprog @ showTree :: (Show a) => Tree a -> String showTree (Leaf x) = show x showTree (Branch l r) = "<" ++ showTree l ++ "|" ++ showTree r ++ ">" @ \eprog Because @(++)@ has time complexity linear in the length of its left argument, @showTree@ is potentially quadratic in the size of the tree. To restore linear complexity, the function @shows@ is provided: \bprog @ shows :: (Show a) => a -> String -> String @ \eprog @shows@ takes a printable value and a string and returns that string with the value's representation concatenated at the front. The second argument serves as a sort of string accumulator, and @show@ can now be defined as @shows@ with the null accumulator. This is the default definition of @show@ in the @Show@ class definition: \bprog @ show x = shows x "" @ \eprog We can use @shows@ to define a more efficient version of @showTree@, which also has a string accumulator argument: \bprog @ showsTree :: (Show a) => Tree a -> String -> String showsTree (Leaf x) s = shows x s showsTree (Branch l r) s= '<' : showsTree l ('|' : showsTree r ('>' : s)) @ \eprog This solves our efficiency problem (@showsTree@ has linear complexity), but the presentation of this function (and others like it) can be improved. First, let's create a type synonym: \bprog @ type ShowS = String -> String @ \eprog This is the type of a function that returns a string representation of something followed by an accumulator string. Second, we can avoid carrying accumulators around, and also avoid amassing parentheses at the right end of long constructions, by using functional composition: \bprog @ showsTree :: (Show a) => Tree a -> ShowS showsTree (Leaf x) = shows x showsTree (Branch l r) = ('<':) . showsTree l . ('|':) . showsTree r . ('>':) @ \eprog Something more important than just tidying up the code has come about by this transformation: we have raised the presentation from an {\em object level} (in this case, strings) to a {\em function level.} We can think of the typing as saying that @showsTree@ maps a tree into a {\em showing function}. Functions like @('<' :)@ or @("a string" ++)@ are primitive showing functions, and we build up more complex functions by function composition. Now that we can turn trees into strings, let's turn to the inverse problem. The basic idea is a parser for a type @a@, which is a function that takes a string and returns a list of @(a, String)@ pairs~\cite{wadler:list-of-successes}. The Prelude provides a type synonym for such functions: \bprog @ type ReadS a = String -> [(a,String)] @ \eprog Normally, a parser returns a singleton list, containing a value of type @a@ that was read from the input string and the remaining string that follows what was parsed. If no parse was possible, however, the result is the empty list, and if there is more than one possible parse (an ambiguity), the resulting list contains more than one pair. The standard function @reads@ is a parser for any instance of @Read@: \bprog @ reads :: (Read a) => ReadS a @ \eprog We can use this function to define a parsing function for the string representation of binary trees produced by @showsTree@. List comprehensions give us a convenient idiom for constructing such parsers:\footnote{An even more elegant approach to parsing uses monads and parser combinators. These are part of a standard parsing library distributed with most Haskell systems.} \bprog @ readsTree :: (Read a) => ReadS (Tree a) readsTree ('<':s) = [(Branch l r, u) | (l, '|':t) <- readsTree s, (r, '>':u) <- readsTree t ] readsTree s = [(Leaf x, t) | (x,t) <- reads s] @ \eprog Let's take a moment to examine this function definition in detail. There are two main cases to consider: If the first character of the string to be parsed is @'<'@, we should have the representation of a branch; otherwise, we have a leaf. In the first case, calling the rest of the input string following the opening angle bracket @s@, any possible parse must be a tree @Branch l r@ with remaining string @u@, subject to the following conditions: \begin{enumerate} \item The tree @l@ can be parsed from the beginning of the string @s@. \item The string remaining (following the representation of @l@) begins with @'|'@. Call the tail of this string @t@. \item The tree @r@ can be parsed from the beginning of @t@. \item The string remaining from that parse begins with @'>'@, and @u@ is the tail. \end{enumerate} Notice the expressive power we get from the combination of pattern matching with list comprehension: the form of a resulting parse is given by the main expression of the list comprehension, the first two conditions above are expressed by the first generator (``@(l, '|':t)@ is drawn from the list of parses of @s@''), and the remaining conditions are expressed by the second generator. The second defining equation above just says that to parse the representation of a leaf, we parse a representation of the element type of the tree and apply the constructor @Leaf@ to the value thus obtained. We'll accept on faith for the moment that there is a @Read@ (and @Show@) instance of @Integer@ (among many other types), providing a @reads@ that behaves as one would expect, e.g.: \[ @(reads "5 golden rings") :: [(Integer,String)]@\ \ \ \ \red\ \ \ \ % @[(5, " golden rings")]@ \] With this understanding, the reader should verify the following evaluations: \[\ba{lcl} @readsTree "<1|<2|3>>"@&\ \ \ \ \red\ \ \ \ & @[(Branch (Leaf 1) (Branch (Leaf 2) (Leaf 3)), "")]@\\ @readsTree "<1|2"@ &\ \ \ \ \red\ \ \ \ & @[]@ \ea\] There are a couple of shortcomings in our definition of @readsTree@. One is that the parser is quite rigid, allowing no white space before or between the elements of the tree representation; the other is that the way we parse our punctuation symbols is quite different from the way we parse leaf values and subtrees, this lack of uniformity making the function definition harder to read. We can address both of these problems by using the lexical analyzer provided by the Prelude: \bprog @ lex :: ReadS String @ \eprog @lex@ normally returns a singleton list containing a pair of strings: the first lexeme in the input string and the remainder of the input. The lexical rules are those of Haskell programs, including comments, which @lex@ skips, along with whitespace. If the input string is empty or contains only whitespace and comments, @lex@ returns @[("","")]@; if the input is not empty in this sense, but also does not begin with a valid lexeme after any leading whitespace and comments, @lex@ returns @[]@. Using the lexical analyzer, our tree parser now looks like this: \bprog @ readsTree :: (Read a) => ReadS (Tree a) readsTree s = [(Branch l r, x) | ("<", t) <- lex s, (l, u) <- readsTree t, ("|", v) <- lex u, (r, w) <- readsTree v, (">", x) <- lex w ] ++ [(Leaf x, t) | (x, t) <- reads s ] @ \eprog We may now wish to use @readsTree@ and @showsTree@ to declare @(Read a) => Tree a@ an instance of @Read@ and @(Show a) => Tree a@ an instance of @Show@. This would allow us to use the generic overloaded functions from the Prelude to parse and display trees. Moreover, we would automatically then be able to parse and display many other types containing trees as components, for example, @[Tree Integer]@. As it turns out, @readsTree@ and @showsTree@ are of almost the right types to be @Show@ and @Read@ methods % , needing % only the addition of an extra parameter each that has do do with % parenthesization of forms with infix constructors. The @showsPrec@ and @readsPrec@ methods are parameterized versions of @shows@ and @reads@. The extra parameter is a precedence level, used to properly parenthesize expressions containing infix constructors. For types such as @Tree@, the precedence can be ignored. The @Show@ and @Read@ instances for @Tree@ are: \bprog @ instance Show a => Show (Tree a) where showsPrec _ x = showsTree x instance Read a => Read (Tree a) where readsPrec _ s = readsTree s @ \eprog Alternatively, the @Show@ instance could be defined in terms of @showTree@: \bprog @ instance Show a => Show (Tree a) where show t = showTree t @ \eprog This, however, will be less efficient than the @ShowS@ version. Note that the @Show@ class defines default methods for both @showsPrec@ and @show@, allowing the user to define either one of these in an instance declaration. Since these defaults are mutually recursive, an instance declaration that defines neither of these functions will loop when called. Other classes such as @Num@ also have these ``interlocking defaults''. We refer the interested reader to \see{derived-appendix} for details of the @Read@ and @Show@ classes. We can test the @Read@ and @Show@ instances by applying @(read . show)@ (which should be the identity) to some trees, where @read@ is a specialization of @reads@: \bprog @ read :: (Read a) => String -> a @ \eprog This function fails if there is not a unique parse or if the input contains anything more than a representation of one value of type @a@ (and possibly, comments and whitespace). \subsection{Derived Instances} \label{tut-derived-instances} Recall the @Eq@ instance for trees we presented in Section \ref{tut-type-classes}; such a declaration is simple---and boring---to produce: we require that the element type in the leaves be an equality type; then, two leaves are equal iff they contain equal elements, and two branches are equal iff their left and right subtrees are equal, respectively. Any other two trees are unequal: \bprog @ instance (Eq a) => Eq (Tree a) where (Leaf x) == (Leaf y) = x == y (Branch l r) == (Branch l' r') = l == l' && r == r' _ == _ = False @ \eprog Fortunately, we don't need to go through this tedium every time we need equality operators for a new type; the @Eq@ instance can be {\em derived automatically} from the @data@ declaration if we so specify: \bprog @ data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Eq @ \eprog The @deriving@ clause implicitly produces an @Eq@ instance declaration just like the one in Section \ref{tut-type-classes}. Instances of @Ord@, @Enum@, @Ix@, @Read@, and @Show@ can also be generated by the @deriving@ clause. \syn{More than one class name can be specified, in which case the list of names must be parenthesized and the names separated by commas.} The derived @Ord@ instance for @Tree@ is slightly more complicated than the @Eq@ instance: \bprog @ instance (Ord a) => Ord (Tree a) where (Leaf _) <= (Branch _) = True (Leaf x) <= (Leaf y) = x <= y (Branch _) <= (Leaf _) = False (Branch l r) <= (Branch l' r') = l == l' && r <= r' || l <= l' @ \eprog This specifies a {\em lexicographic} order: Constructors are ordered by the order of their appearance in the @data@ declaration, and the arguments of a constructor are compared from left to right. Recall that the built-in list type is semantically equivalent to an ordinary two-constructor type. In fact, this is the full declaration: \bprog @ data [a] = [] | a : [a] deriving (Eq, Ord) -- pseudo-code @ \eprog (Lists also have @Show@ and @Read@ instances, which are not derived.) The derived @Eq@ and @Ord@ instances for lists are the usual ones; in particular, character strings, as lists of characters, are ordered as determined by the underlying @Char@ type, with an initial substring comparing less than a longer string; for example, @"cat" < "catalog"@. In practice, @Eq@ and @Ord@ instances are almost always derived, rather than user-defined. In fact, we should provide our own definitions of equality and ordering predicates only with some trepidation, being careful to maintain the expected algebraic properties of equivalence relations and total orders. An intransitive @(==)@ predicate, for example, could be disastrous, confusing readers of the program and confounding manual or automatic program transformations that rely on the @(==)@ predicate's being an approximation to definitional equality. Nevertheless, it is sometimes necessary to provide @Eq@ or @Ord@ instances different from those that would be derived; probably the most important example is that of an abstract data type in which different concrete values may represent the same abstract value. An enumerated type can have a derived @Enum@ instance, and here again, the ordering is that of the constructors in the @data@ declaration. For example: \bprog @ data Day = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday deriving (Enum) @ \eprog Here are some simple examples using the derived instances for this type: \[\ba{lcl} @[Wednesday .. Friday]@ \ \ &\red&\ \ @[Wednesday, Thursday, Friday]@\\ @[Monday, Wednesday ..]@\ \ &\red&\ \ @[Monday, Wednesday, Friday]@ \ea\] Derived @Read@ (@Show@) instances are possible for all types whose component types also have @Read@ (@Show@) instances. (@Read@ and @Show@ instances for most of the standard types are provided by the Prelude. Some types, such as the function type @(->)@, have a @Show@ instance but not a corresponding @Read@.) The textual representation defined by a derived @Show@ instance is consistent with the appearance of constant Haskell expressions of the type in question. For example, if we add @Show@ and @Read@ to the @deriving@ clause for type @Day@, above, we obtain \[ @show [Monday .. Wednesday]@\ \ \ \ \red\ \ \ \ @"[Monday,Tuesday,Wednesday]"@ \] %**~footer haskell-98-tutorial-sources/haskell-tutorial.bbl0100644000106400000620000000376206774446522020377 0ustar jcpftp%**A Gentle Introduction to Haskell: Bibliography %**~eheader \begin{thebibliography}{1} \bibitem{bird98} R.~Bird. \newblock {\em Introduction to Functional Programming using Haskell}. \newblock Prentice Hall, New York, 1998. \bibitem{davie92} A.Davie. \newblock {\em Introduction to Functional Programming System Using Haskell}. \newblock Cambridge University Press, 1992. \bibitem{huda89a} P.~Hudak. \newblock Conception, evolution, and application of functional programming languages. \newblock {\em ACM Computing Surveys}, 21(3):359--411, 1989. \bibitem{haskell-98} Simon Peyton Jones (editor). \newblock Report on the {P}rogramming {L}anguage {H}askell 98, {A} {N}on-strict {P}urely {F}unctional {L}anguage. \newblock {\em Yale University, Department of Computer Science Tech Report YALEU/DCS/RR-1106}, Feb 1999. \bibitem{haskell-libs} Simon Peyton Jones (editor) \newblock The Haskell 98 Library Report. \newblock {\em Yale University, Department of Computer Science Tech Report YALEU/DCS/RR-1105}, Feb 1999. \bibitem{id-manual} R.S. Nikhil. \newblock Id (version 90.0) reference manual. \newblock Technical report, Massachusetts Institute of Technology, Laboratory for Computer Science, September 1990. \bibitem{RRRRS} J.~Rees and W.~Clinger~(eds.). \newblock The revised$^3$ report on the algorithmic language {S}cheme. \newblock {\em SIGPLAN Notices}, 21(12):37--79, December 1986. \bibitem{steele:common-lisp} G.L. {Steele Jr.} \newblock {\em {Common} {Lisp}: The Language}. \newblock Digital Press, Burlington, Mass., 1984. \bibitem{wadler:list-of-successes} P.~Wadler. \newblock How to replace failure by a list of successes. \newblock In {\em Proceedings of Conference on Functional Programming Languages and Computer Architecture, LNCS Vol. 201}, pages 113--128. Springer Verlag, 1985. \bibitem{wadler:mffp} P.~Wadler. \newblock Monads for Functional Programming \newblock In {\em Advanced Functional Programming }, Springer Verlag, LNCS 925, 1995. \end{thebibliography} %**~efooter haskell-98-tutorial-sources/report-refs.tex0100644000106400000620000000755306774446522017426 0ustar jcpftp\newlabel{introduction}{{1}{1}} \newlabel{programs}{{1.1}{1}} \newlabel{intro-kernel}{{1.2}{2}} \newlabel{errors}{{1.3}{2}} \newlabel{namespaces}{{1.4}{2}} \newlabel{lexical-structure}{{2}{4}} \newlabel{notational-conventions}{{2.1}{4}} \newlabel{lexemes}{{2.2}{5}} \newlabel{whitespace}{{2.2}{5}} \newlabel{ids}{{2.4}{6}} \newlabel{lexemes-numeric}{{2.5}{8}} \newlabel{lexemes-char}{{2.6}{8}} \newlabel{lexemes-layout}{{2.7}{9}} \newlabel{layout-before}{{1}{11}} \newlabel{layout-after}{{2}{11}} \newlabel{expressions}{{3}{12}} \newlabel{syntax-precedences}{{1}{13}} \newlabel{basic-errors}{{3.1}{14}} \newlabel{applications}{{3.3}{16}} \newlabel{lambda-abstractions}{{3.3}{16}} \newlabel{operators}{{3.4}{16}} \newlabel{sections}{{3.5}{17}} \newlabel{conditionals}{{3.6}{17}} \newlabel{lists}{{3.7}{18}} \newlabel{tuples}{{3.8}{18}} \newlabel{unit-expression}{{3.9}{18}} \newlabel{arithmetic-sequences}{{3.10}{19}} \newlabel{list-comprehensions}{{3.11}{19}} \newlabel{let-expressions}{{3.12}{21}} \newlabel{case}{{3.13}{21}} \newlabel{do-expressions}{{3.14}{22}} \newlabel{field-ops}{{3.15}{23}} \newlabel{expression-type-sigs}{{3.16}{25}} \newlabel{pattern-matching}{{3.17}{26}} \newlabel{patterns}{{3.17}{26}} \newlabel{pattern-definitions}{{3.17.1}{26}} \newlabel{case-semantics}{{3.17.3}{29}} \newlabel{simple-case-expr-1}{{3}{30}} \newlabel{simple-case-expr-2}{{4}{31}} \newlabel{declarations}{{4}{32}} \newlabel{types-overview}{{4.1}{33}} \newlabel{type-syntax}{{4.1.1}{34}} \newlabel{types}{{4.1.1}{34}} \newlabel{classes&contexts}{{4.1.2}{36}} \newlabel{type-semantics}{{4.1.3}{36}} \newlabel{user-defined-datatypes}{{4.2}{37}} \newlabel{datatype-decls}{{4.2.1}{38}} \newlabel{field-labels}{{4.2.1}{39}} \newlabel{strictness-flags}{{4.2.1}{39}} \newlabel{type-synonym-decls}{{4.2.2}{40}} \newlabel{datatype-renaming}{{4.2.3}{41}} \newlabel{overloading}{{4.3}{42}} \newlabel{classes}{{4.3}{42}} \newlabel{class-decls}{{4.3.1}{42}} \newlabel{instance-decls}{{4.3.2}{43}} \newlabel{derived-decls}{{4.3.3}{45}} \newlabel{default-decls}{{4.3.4}{45}} \newlabel{nested}{{4.4}{47}} \newlabel{type-signatures}{{4.4.1}{47}} \newlabel{function-bindings}{{4.4.2}{48}} \newlabel{pattern-bindings}{{4.4.2}{48}} \newlabel{dependencyanalysis}{{4.5}{50}} \newlabel{generalization}{{4.5.2}{51}} \newlabel{context-reduction}{{4.5.3}{52}} \newlabel{monomorphism}{{4.5.4}{52}} \newlabel{sect:monomorphism-restriction}{{4.5.5}{53}} \newlabel{kindinference}{{4.6}{56}} \newlabel{modules}{{5}{57}} \newlabel{module-implementations}{{5.1}{57}} \newlabel{export}{{5.2}{58}} \newlabel{import}{{5.3}{59}} \newlabel{as-clause}{{5.3.2}{61}} \newlabel{qualifiers}{{5.5.1}{61}} \newlabel{closure}{{5.5.3}{63}} \newlabel{standard-prelude}{{5.6}{64}} \newlabel{std-prel-shadowing}{{5.6.2}{65}} \newlabel{abstract-types}{{5.8}{66}} \newlabel{fixity}{{5.9}{66}} \newlabel{prelude-fixities}{{2}{67}} \newlabel{basic-types-and-classes}{{6}{68}} \newlabel{basic-types}{{6.1}{68}} \newlabel{booleans}{{6.1.1}{68}} \newlabel{prelude-bool}{{6.1.1}{68}} \newlabel{characters}{{6.1.2}{68}} \newlabel{basic-lists}{{6.1.3}{69}} \newlabel{basic-tuples}{{6.1.4}{69}} \newlabel{basic-trivial}{{6.1.5}{69}} \newlabel{strict-eval}{{6.2}{70}} \newlabel{standard-classes}{{5}{72}} \newlabel{monad-class}{{6.3.6}{76}} \newlabel{numbers}{{6.4}{77}} \newlabel{numeric-literals}{{6.4.1}{77}} \newlabel{standard-numeric-types}{{3}{78}} \newlabel{arithmetic-operators}{{6.4.2}{78}} \newlabel{basic-numeric-1}{{6}{79}} \newlabel{magnitude-sign}{{6.4.4}{79}} \newlabel{basic-numeric-2}{{7}{80}} \newlabel{coercion}{{6.4.6}{81}} \newlabel{io}{{7}{83}} \newlabel{stdprelude}{{A}{87}} \newlabel{preludelist}{{A.1}{101}} \newlabel{preludetext}{{A.2}{108}} \newlabel{preludeio}{{A.3}{113}} \newlabel{syntax}{{B}{115}} \newlabel{layout}{{B.3}{118}} \newlabel{bnf}{{B.4}{121}} \newlabel{literate}{{C}{126}} \newlabel{derived-appendix}{{D}{128}} \newlabel{tree-inst}{{8}{132}} \newlabel{pragmas}{{E}{133}} haskell-98-tutorial-sources/reportrefs0100644000106400000620000002405106774446522016542 0ustar jcpftp$wadler:classes=haskell $unicode=haskell $peyton-jones:book=haskell $libraries=haskell $penfield:complex-apl=haskell $jones:cclasses=haskell $tutorial=haskell $hindley69=haskell $damas-milner82=haskell $curry&feys:book=haskell $back78=haskell sectE.3=pragmas sectE.2=pragmas sectE.1=pragmas pragmas=pragmas sectE=pragmas tree-inst=derived sectD.1=derived derived-appendix=derived sectD=derived literate=literate sectC=literate bnf=syntax-iso sectB.4=syntax-iso layout=syntax-iso sectB.3=syntax-iso sectB.2=syntax-iso sectB.1=syntax-iso syntax=syntax-iso sectB=syntax-iso $vreadLn=standard-prelude $vreadIO=standard-prelude $vappendFile=standard-prelude $vwriteFile=standard-prelude $vreadFile=standard-prelude $vinteract=standard-prelude $vgetContents=standard-prelude $vgetLine=standard-prelude $vgetChar=standard-prelude $vprint=standard-prelude $vputStrLn=standard-prelude $vputStr=standard-prelude $vputChar=standard-prelude $vcatch=standard-prelude $vuserError=standard-prelude $vioError=standard-prelude $iEq$$IOError=standard-prelude $iShow$$IOError=standard-prelude $tIOError=standard-prelude $tFilePath=standard-prelude preludeio=standard-prelude sectA.3=standard-prelude $iShow$$IO=standard-prelude $iShow$$a$D$Ab=standard-prelude $iRead$$$Pa$xb$C=standard-prelude $iShow$$$Pa$xb$C=standard-prelude $iRead$$$Ba$c=standard-prelude $iShow$$$Ba$c=standard-prelude $iRead$$Char=standard-prelude $iShow$$Char=standard-prelude $iRead$$$P$C=standard-prelude $iShow$$$P$C=standard-prelude $iRead$$Double=standard-prelude $iShow$$Double=standard-prelude $iRead$$Float=standard-prelude $iShow$$Float=standard-prelude $iRead$$Integer=standard-prelude $iShow$$Integer=standard-prelude $iRead$$Int=standard-prelude $iShow$$Int=standard-prelude $vlex=standard-prelude $vreadParen=standard-prelude $vshowParen=standard-prelude $vshowString=standard-prelude $vshowChar=standard-prelude $vshow=standard-prelude $vread=standard-prelude $vshows=standard-prelude $vreads=standard-prelude $tShow=standard-prelude $tRead=standard-prelude $tShowS=standard-prelude $tReadS=standard-prelude preludetext=standard-prelude sectA.2=standard-prelude $vunzip3=standard-prelude $vunzip=standard-prelude $vzipWith3=standard-prelude $vzipWith=standard-prelude $vzip3=standard-prelude $vzip=standard-prelude $vconcatMap=standard-prelude $vmaximum=standard-prelude $vminimum=standard-prelude $vsum=standard-prelude $vproduct=standard-prelude $vlookup=standard-prelude $velem=standard-prelude $vnotElem=standard-prelude $vany=standard-prelude $vall=standard-prelude $vand=standard-prelude $vor=standard-prelude $vreverse=standard-prelude $vunwords=standard-prelude $vunlines=standard-prelude $vwords=standard-prelude $vlines=standard-prelude $vspan=standard-prelude $vbreak=standard-prelude $vdropWhile=standard-prelude $vtakeWhile=standard-prelude $vsplitAt=standard-prelude $vdrop=standard-prelude $vtake=standard-prelude $vcycle=standard-prelude $vreplicate=standard-prelude $vrepeat=standard-prelude $viterate=standard-prelude $vscanr1=standard-prelude $vscanr=standard-prelude $vfoldr1=standard-prelude $vfoldr=standard-prelude $vscanl1=standard-prelude $vscanl=standard-prelude $vfoldl1=standard-prelude $vfoldl=standard-prelude $v$E$E=standard-prelude $vlength=standard-prelude $vnull=standard-prelude $vinit=standard-prelude $vtail=standard-prelude $vlast=standard-prelude $vhead=standard-prelude $vconcat=standard-prelude $vfilter=standard-prelude $v++=standard-prelude $vmap=standard-prelude preludelist=standard-prelude sectA.1=standard-prelude $vundefined=standard-prelude $verror=standard-prelude $vasTypeOf=standard-prelude $vuntil=standard-prelude $vuncurry=standard-prelude $vcurry=standard-prelude $vsnd=standard-prelude $vfst=standard-prelude $t$Pa$xb$xc$C=standard-prelude $t$Pa$xb$C=standard-prelude $iMonad$$$Ba$c=standard-prelude $iFunctor$$$Ba$c=standard-prelude $t$Ba$c=standard-prelude $vnumericEnumFromThenTo=standard-prelude $vnumericEnumFromTo=standard-prelude $vnumericEnumFromThen=standard-prelude $vnumericEnumFrom=standard-prelude $iEnum$$Double=standard-prelude $iEnum$$Float=standard-prelude $iRealFloat$$Double=standard-prelude $iRealFrac$$Double=standard-prelude $iFloating$$Double=standard-prelude $iFractional$$Double=standard-prelude $iReal$$Double=standard-prelude $iNum$$Double=standard-prelude $iOrd$$Double=standard-prelude $iEq$$Double=standard-prelude $tDouble=standard-prelude $iRealFloat$$Float=standard-prelude $iRealFrac$$Float=standard-prelude $iFloating$$Float=standard-prelude $iFractional$$Float=standard-prelude $iReal$$Float=standard-prelude $iNum$$Float=standard-prelude $iOrd$$Float=standard-prelude $iEq$$Float=standard-prelude $tFloat=standard-prelude $iEnum$$Integer=standard-prelude $iIntegral$$Integer=standard-prelude $iReal$$Integer=standard-prelude $iNum$$Integer=standard-prelude $iOrd$$Integer=standard-prelude $iEq$$Integer=standard-prelude $tInteger=standard-prelude $iBounded$$Int=standard-prelude $iEnum$$Int=standard-prelude $iIntegral$$Int=standard-prelude $iReal$$Int=standard-prelude $iNum$$Int=standard-prelude $iOrd$$Int=standard-prelude $iEq$$Int=standard-prelude $tInt=standard-prelude $tOrdering=standard-prelude $iMonad$$IO=standard-prelude $iFunctor$$IO=standard-prelude $tIO=standard-prelude $veither=standard-prelude $tEither=standard-prelude $iMonad$$Maybe=standard-prelude $iFunctor$$Maybe=standard-prelude $vmaybe=standard-prelude $tMaybe=standard-prelude $tString=standard-prelude $iBounded$$Char=standard-prelude $iEnum$$Char=standard-prelude $iOrd$$Char=standard-prelude $iEq$$Char=standard-prelude $tChar=standard-prelude $votherwise=standard-prelude $vnot=standard-prelude $v$A$A=standard-prelude $v$b$b=standard-prelude $tBool=standard-prelude $v$D=standard-prelude $v$D$E=standard-prelude $vflip=standard-prelude $v.=standard-prelude $vconst=standard-prelude $vid=standard-prelude $ta=standard-prelude $t$P$C=standard-prelude $v$Q$L$L=standard-prelude $vmapM_=standard-prelude $vmapM=standard-prelude $vsequence_=standard-prelude $vsequence=standard-prelude $tMonad=standard-prelude $tFunctor=standard-prelude $vrealToFrac=standard-prelude $vfromIntegral=standard-prelude $v$U$U=standard-prelude $v$U=standard-prelude $vlcm=standard-prelude $vgcd=standard-prelude $veven=standard-prelude $vodd=standard-prelude $vsubtract=standard-prelude $tRealFloat=standard-prelude $tRealFrac=standard-prelude $tFloating=standard-prelude $tFractional=standard-prelude $tIntegral=standard-prelude $tReal=standard-prelude $tNum=standard-prelude $tBounded=standard-prelude $tEnum=standard-prelude $tOrd=standard-prelude $tEq=standard-prelude stdprelude=standard-prelude sectA=standard-prelude sect7.3=io-13 sect7.2=io-13 sect7.1=io-13 io=io-13 sect7=io-13 coercion=basic sect6.4.6=basic sect6.4.5=basic magnitude-sign=basic sect6.4.4=basic sect6.4.3=basic arithmetic-operators=basic sect6.4.2=basic numeric-literals=basic sect6.4.1=basic basic-numeric-2=basic basic-numeric-1=basic standard-numeric-types=basic numbers=basic sect6.4=basic sect6.3.7=basic monad-class=basic sect6.3.6=basic sect6.3.5=basic sect6.3.4=basic sect6.3.3=basic sect6.3.2=basic sect6.3.1=basic standard-classes=basic sect6.3=basic strict-eval=basic sect6.2=basic sect6.1.8=basic sect6.1.7=basic sect6.1.6=basic basic-trivial=basic sect6.1.5=basic basic-tuples=basic sect6.1.4=basic basic-lists=basic sect6.1.3=basic characters=basic sect6.1.2=basic prelude-bool=basic booleans=basic sect6.1.1=basic basic-types=basic sect6.1=basic basic-types-and-classes=basic sect6=basic prelude-fixities=modules fixity=modules sect5.9=modules abstract-types=modules sect5.8=modules sect5.7=modules std-prel-shadowing=modules sect5.6.2=modules sect5.6.1=modules standard-prelude=modules sect5.6=modules closure=modules sect5.5.3=modules sect5.5.2=modules qualifiers=modules sect5.5.1=modules sect5.5=modules sect5.4=modules as-clause=modules sect5.3.2=modules sect5.3.1=modules import=modules sect5.3=modules export=modules sect5.2=modules module-implementations=modules sect5.1=modules modules=modules sect5=modules kindinference=decls sect4.6=decls sect:monomorphism-restriction=decls sect4.5.5=decls monomorphism=decls sect4.5.4=decls context-reduction=decls sect4.5.3=decls generalization=decls sect4.5.2=decls sect4.5.1=decls dependencyanalysis=decls sect4.5=decls pattern-bindings=decls function-bindings=decls sect4.4.2=decls type-signatures=decls sect4.4.1=decls nested=decls sect4.4=decls default-decls=decls sect4.3.4=decls derived-decls=decls sect4.3.3=decls instance-decls=decls sect4.3.2=decls class-decls=decls sect4.3.1=decls classes=decls overloading=decls sect4.3=decls datatype-renaming=decls sect4.2.3=decls type-synonym-decls=decls sect4.2.2=decls strictness-flags=decls field-labels=decls datatype-decls=decls sect4.2.1=decls user-defined-datatypes=decls sect4.2=decls type-semantics=decls sect4.1.3=decls classes&contexts=decls sect4.1.2=decls types=decls type-syntax=decls sect4.1.1=decls types-overview=decls sect4.1=decls declarations=decls sect4=decls simple-case-expr-2=exps case-semantics=exps sect3.17.3=exps simple-case-expr-1=exps sect3.17.2=exps pattern-definitions=exps sect3.17.1=exps patterns=exps pattern-matching=exps sect3.17=exps expression-type-sigs=exps sect3.16=exps sect3.15.3=exps sect3.15.2=exps sect3.15.1=exps field-ops=exps sect3.15=exps do-expressions=exps sect3.14=exps case=exps sect3.13=exps let-expressions=exps sect3.12=exps list-comprehensions=exps sect3.11=exps arithmetic-sequences=exps sect3.10=exps unit-expression=exps sect3.9=exps tuples=exps sect3.8=exps lists=exps sect3.7=exps conditionals=exps sect3.6=exps sections=exps sect3.5=exps operators=exps sect3.4=exps lambda-abstractions=exps applications=exps sect3.3=exps sect3.2=exps basic-errors=exps sect3.1=exps syntax-precedences=exps expressions=exps sect3=exps layout-after=lexemes layout-before=lexemes lexemes-layout=lexemes sect2.7=lexemes lexemes-char=lexemes sect2.6=lexemes lexemes-numeric=lexemes sect2.5=lexemes ids=lexemes sect2.4=lexemes sect2.3=lexemes whitespace=lexemes lexemes=lexemes sect2.2=lexemes notational-conventions=lexemes sect2.1=lexemes lexical-structure=lexemes sect2=lexemes namespaces=intro sect1.4=intro errors=intro sect1.3=intro intro-kernel=intro sect1.2=intro programs=intro sect1.1=intro introduction=intro sect1=intro haskell-98-tutorial-sources/fig1.eps0100644000106400000620000013241106774446522015763 0ustar jcpftp%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: -300 459 438 775 %%Creator: CorelDRAW %%Title: %%CreationDate: Mon Mar 10 17:09:26 1997 %%DocumentProcessColors: Black %%DocumentSuppliedResources: (atend) %%EndComments %%BeginProlog /AutoFlatness true def /AutoSteps 0 def /CMYKMarks false def /UseLevel2 false def %Color profile: Disabled %%BeginResource: procset wCorel6Dict 6.0 0 % Copyright (c)1992-96 Corel Corporation % All rights reserved. v6.0 r1.1 /wCorel6Dict 300 dict def wCorel6Dict begin/bd{bind def}bind def/ld{load def} bd/xd{exch def}bd/_ null def/rp{{pop}repeat}bd/@cp/closepath ld/@gs/gsave ld /@gr/grestore ld/@np/newpath ld/Tl/translate ld/$sv 0 def/@sv{/$sv save def}bd /@rs{$sv restore}bd/spg/showpage ld/showpage{}bd currentscreen/@dsp xd/$dsp /@dsp def/$dsa xd/$dsf xd/$sdf false def/$SDF false def/$Scra 0 def/SetScr /setscreen ld/setscreen{pop pop pop}bd/@ss{2 index 0 eq{$dsf 3 1 roll 4 -1 roll pop}if exch $Scra add exch load SetScr}bd/SepMode_5 where{pop}{/SepMode_5 0 def}ifelse/CurrentInkName_5 where{pop}{/CurrentInkName_5(Composite)def}ifelse /$ink_5 where{pop}{/$ink_5 -1 def}ifelse/$c 0 def/$m 0 def/$y 0 def/$k 0 def /$t 1 def/$n _ def/$o 0 def/$fil 0 def/$C 0 def/$M 0 def/$Y 0 def/$K 0 def/$T 1 def/$N _ def/$O 0 def/$PF false def/s1c 0 def/s1m 0 def/s1y 0 def/s1k 0 def /s1t 0 def/s1n _ def/$bkg false def/SK 0 def/SM 0 def/SY 0 def/SC 0 def/$op false def matrix currentmatrix/$ctm xd/$ptm matrix def/$ttm matrix def/$stm matrix def/$fst 128 def/$pad 0 def/$rox 0 def/$roy 0 def/$fmp 50 def/$ffpnt true def/CorelDrawReencodeVect[16#0/grave 16#5/breve 16#6/dotaccent 16#8/ring 16#A/hungarumlaut 16#B/ogonek 16#C/caron 16#D/dotlessi 16#27/quotesingle 16#60/grave 16#7C/bar 16#82/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl 16#88/circumflex/perthousand/Scaron/guilsinglleft/OE 16#91/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash 16#98/tilde/trademark/scaron/guilsinglright/oe 16#9F/Ydieresis 16#A1/exclamdown/cent/sterling/currency/yen/brokenbar/section 16#a8/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/minus/registered/macron 16#b0/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered 16#b8/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown 16#c0/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla 16#c8/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis 16#d0/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply 16#d8/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls 16#e0/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla 16#e8/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis 16#f0/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide 16#f8/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def /L2?/languagelevel where{pop languagelevel 2 ge}{false}ifelse def /@BeginSysCorelDict{systemdict/Corel30Dict known{systemdict/Corel30Dict get exec}if}bd/@EndSysCorelDict{systemdict/Corel30Dict known{end}if}bd AutoFlatness {/@ifl{dup currentflat exch sub 10 gt{ ([Error: PathTooComplex; OffendingCommand: AnyPaintingOperator]\n)print flush @np exit}{currentflat 2 add setflat}ifelse}bd/@fill/fill ld/fill{currentflat{ {@fill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@eofill/eofill ld/eofill {currentflat{{@eofill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@clip /clip ld/clip{currentflat{{@clip}stopped{@ifl}{exit}ifelse}bind loop setflat} bd/@eoclip/eoclip ld/eoclip{currentflat{{@eoclip}stopped{@ifl}{exit}ifelse} bind loop setflat}bd/@stroke/stroke ld/stroke{currentflat{{@stroke}stopped {@ifl}{exit}ifelse}bind loop setflat}bd}if L2?{/@ssa{true setstrokeadjust}bd}{ /@ssa{}bd}ifelse/d/setdash ld/j/setlinejoin ld/J/setlinecap ld/M/setmiterlimit ld/w/setlinewidth ld/O{/$o xd}bd/R{/$O xd}bd/W/eoclip ld/c/curveto ld/C/c ld/l /lineto ld/L/l ld/rl/rlineto ld/m/moveto ld/n/newpath ld/N/newpath ld/P{11 rp} bd/u{}bd/U{}bd/A{pop}bd/q/@gs ld/Q/@gr ld/&{}bd/@j{@sv @np}bd/@J{@rs}bd/g{1 exch sub/$k xd/$c 0 def/$m 0 def/$y 0 def/$t 1 def/$n _ def/$fil 0 def}bd/G{1 sub neg/$K xd _ 1 0 0 0/$C xd/$M xd/$Y xd/$T xd/$N xd}bd/k{1 index type /stringtype eq{/$t xd/$n xd}{/$t 0 def/$n _ def}ifelse/$k xd/$y xd/$m xd/$c xd /$fil 0 def}bd/K{1 index type/stringtype eq{/$T xd/$N xd}{/$T 0 def/$N _ def} ifelse/$K xd/$Y xd/$M xd/$C xd}bd/x/k ld/X/K ld/sf{1 index type/stringtype eq{ /s1t xd/s1n xd}{/s1t 0 def/s1n _ def}ifelse/s1k xd/s1y xd/s1m xd/s1c xd}bd/i{ dup 0 ne{setflat}{pop}ifelse}bd/v{4 -2 roll 2 copy 6 -2 roll c}bd/V/v ld/y{2 copy c}bd/Y/y ld/@w{matrix rotate/$ptm xd matrix scale $ptm dup concatmatrix /$ptm xd 1 eq{$ptm exch dup concatmatrix/$ptm xd}if 1 w}bd/@g{1 eq dup/$sdf xd {/$scp xd/$sca xd/$scf xd}if}bd/@G{1 eq dup/$SDF xd{/$SCP xd/$SCA xd/$SCF xd} if}bd/@D{2 index 0 eq{$dsf 3 1 roll 4 -1 roll pop}if 3 copy exch $Scra add exch load SetScr/$dsp xd/$dsa xd/$dsf xd}bd/$ngx{$SDF{$SCF SepMode_5 0 eq{$SCA} {$dsa}ifelse $SCP @ss}if}bd/p{/$pm xd 7 rp/$pyf xd/$pxf xd/$pn xd/$fil 1 def} bd/@MN{2 copy le{pop}{exch pop}ifelse}bd/@MX{2 copy ge{pop}{exch pop}ifelse}bd /InRange{3 -1 roll @MN @MX}bd/wDstChck{2 1 roll dup 3 -1 roll eq{1 add}if}bd /@dot{dup mul exch dup mul add 1 exch sub}bd/@lin{exch pop abs 1 exch sub}bd /cmyk2rgb{3{dup 5 -1 roll add 1 exch sub dup 0 lt{pop 0}if exch}repeat pop}bd /rgb2cmyk{3{1 exch sub 3 1 roll}repeat 3 copy @MN @MN 3{dup 5 -1 roll sub neg exch}repeat}bd/rgb2g{2 index .299 mul 2 index .587 mul add 1 index .114 mul add 4 1 roll pop pop pop}bd/WaldoColor_5 where{pop}{/SetRgb/setrgbcolor ld/GetRgb /currentrgbcolor ld/SetGry/setgray ld/GetGry/currentgray ld/SetRgb2 systemdict /setrgbcolor get def/GetRgb2 systemdict/currentrgbcolor get def/SetHsb systemdict/sethsbcolor get def/GetHsb systemdict/currenthsbcolor get def /rgb2hsb{SetRgb2 GetHsb}bd/hsb2rgb{3 -1 roll dup floor sub 3 1 roll SetHsb GetRgb2}bd/setcmykcolor where{pop/SetCmyk_5/setcmykcolor ld}{/SetCmyk_5{ cmyk2rgb SetRgb}bd}ifelse/currentcmykcolor where{pop/GetCmyk/currentcmykcolor ld}{/GetCmyk{GetRgb rgb2cmyk}bd}ifelse/setoverprint where{pop}{/setoverprint{ /$op xd}bd}ifelse/currentoverprint where{pop}{/currentoverprint{$op}bd}ifelse /@tc_5{5 -1 roll dup 1 ge{pop}{4{dup 6 -1 roll mul exch}repeat pop}ifelse}bd /@trp{exch pop 5 1 roll @tc_5}bd/setprocesscolor_5{SepMode_5 0 eq{SetCmyk_5}{0 4 $ink_5 sub index exch pop 5 1 roll pop pop pop pop SepsColor true eq{$ink_5 3 gt{1 sub neg SetGry}{0 0 0 4 $ink_5 roll SetCmyk_5}ifelse}{1 sub neg SetGry} ifelse}ifelse}bd/findcmykcustomcolor where{pop}{/findcmykcustomcolor{5 array astore}bd}ifelse/setcustomcolor where{pop}{/setcustomcolor{exch aload pop SepMode_5 0 eq{pop @tc_5 setprocesscolor_5}{CurrentInkName_5 eq{4 index}{0} ifelse 6 1 roll 5 rp 1 sub neg SetGry}ifelse}bd}ifelse/@scc_5{dup type /booleantype eq{setoverprint}{1 eq setoverprint}ifelse dup _ eq{pop setprocesscolor_5 pop}{findcmykcustomcolor exch setcustomcolor}ifelse SepMode_5 0 eq{true}{GetGry 1 eq currentoverprint and not}ifelse}bd/colorimage where{pop /ColorImage{colorimage}def}{/ColorImage{/ncolors xd pop/dataaq xd{dataaq ncolors dup 3 eq{/$dat xd 0 1 $dat length 3 div 1 sub{dup 3 mul $dat 1 index get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div rgb2g 255 mul cvi exch pop $dat 3 1 roll put}for $dat 0 $dat length 3 idiv getinterval pop}{4 eq{/$dat xd 0 1 $dat length 4 div 1 sub{dup 4 mul $dat 1 index get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div $dat 4 index 3 add get 255 div cmyk2rgb rgb2g 255 mul cvi exch pop $dat 3 1 roll put}for $dat 0 $dat length ncolors idiv getinterval}if}ifelse}image}bd }ifelse/setcmykcolor{1 5 1 roll _ currentoverprint @scc_5/$ffpnt xd}bd /currentcmykcolor{0 0 0 0}bd/setrgbcolor{rgb2cmyk setcmykcolor}bd /currentrgbcolor{currentcmykcolor cmyk2rgb}bd/sethsbcolor{hsb2rgb setrgbcolor} bd/currenthsbcolor{currentrgbcolor rgb2hsb}bd/setgray{dup dup setrgbcolor}bd /currentgray{currentrgbcolor rgb2g}bd}ifelse/WaldoColor_5 true def/@sft{$tllx $pxf add dup $tllx gt{$pwid sub}if/$tx xd $tury $pyf sub dup $tury lt{$phei add}if/$ty xd}bd/@stb{pathbbox/$ury xd/$urx xd/$lly xd/$llx xd}bd/@ep{{cvx exec }forall}bd/@tp{@sv/$in true def 2 copy dup $lly le{/$in false def}if $phei sub $ury ge{/$in false def}if dup $urx ge{/$in false def}if $pwid add $llx le{/$in false def}if $in{@np 2 copy m $pwid 0 rl 0 $phei neg rl $pwid neg 0 rl 0 $phei rl clip @np $pn cvlit load aload pop 7 -1 roll 5 index sub 7 -1 roll 3 index sub Tl matrix currentmatrix/$ctm xd @ep pop pop pop pop}{pop pop}ifelse @rs}bd /@th{@sft 0 1 $tly 1 sub{dup $psx mul $tx add{dup $llx gt{$pwid sub}{exit} ifelse}loop exch $phei mul $ty exch sub 0 1 $tlx 1 sub{$pwid mul 3 copy 3 -1 roll add exch @tp pop}for pop pop}for}bd/@tv{@sft 0 1 $tlx 1 sub{dup $pwid mul $tx add exch $psy mul $ty exch sub{dup $ury lt{$phei add}{exit}ifelse}loop 0 1 $tly 1 sub{$phei mul 3 copy sub @tp pop}for pop pop}for}bd/@pf{@gs $ctm setmatrix $pm concat @stb eoclip Bburx Bbury $pm itransform/$tury xd/$turx xd Bbllx Bblly $pm itransform/$tlly xd/$tllx xd/$wid $turx $tllx sub def/$hei $tury $tlly sub def @gs $vectpat{1 0 0 0 0 _ $o @scc_5{eofill}if}{$t $c $m $y $k $n $o @scc_5{SepMode_5 0 eq $pfrg or{$tllx $tlly Tl $wid $hei scale <00> 8 1 false[8 0 0 1 0 0]{}imagemask}{/$bkg true def}ifelse}if}ifelse @gr $wid 0 gt $hei 0 gt and{$pn cvlit load aload pop/$pd xd 3 -1 roll sub/$phei xd exch sub /$pwid xd $wid $pwid div ceiling 1 add/$tlx xd $hei $phei div ceiling 1 add /$tly xd $psx 0 eq{@tv}{@th}ifelse}if @gr @np/$bkg false def}bd/@dlt_hsb{$fco nff ge{/$fco nff 1 sub def}if sub neg 2 div dup $fco div/kdb xd nff $fco sub div/kdb2 xd sub neg 2 div dup $fco div/kds xd nff $fco sub div/kds2 xd sub neg dup 0 eq{pop $frb 2 eq{.99}{-.99}ifelse}if dup $frb 2 eq exch 0 lt and{1 add} if dup $frb 1 eq exch 0 gt and{1 sub}if 2 div dup $fco div/kdh xd nff $fco sub div/kdh2 xd}bd/@dlt_cmyk{$fmp 50 eq{sub neg nff dup 1 gt{1 sub}if div/$dk xd sub neg nff dup 1 gt{1 sub}if div/$dy xd sub neg nff dup 1 gt{1 sub}if div/$dm xd sub neg nff dup 1 gt{1 sub}if div/$dc xd sub neg nff dup 1 gt{1 sub}if div /$dt xd}{$fco nff ge{/$fco nff 1 sub def}if sub neg 2 div dup $fco div/$dk xd nff $fco sub div/$dk2 xd sub neg 2 div dup $fco div/$dy xd nff $fco sub div /$dy2 xd sub neg 2 div dup $fco div/$dm xd nff $fco sub div/$dm2 xd sub neg 2 div dup $fco div/$dc xd nff $fco sub div/$dc2 xd sub neg 2 div dup $fco div /$dt xd nff $fco sub div/$dt2 xd}ifelse}bd/@dlt{$fse $fss sub dup/nff xd $fmp mul $fmp add 100 div round cvi dup 0 le{pop 1}if/$fco xd/$fi 0 def $frb dup 1 eq exch 2 eq or{$frt dup $frc $frm $fry $frk @tc_5 4 copy cmyk2rgb rgb2hsb 3 copy/myb xd/mys xd/myh xd $tot $toc $tom $toy $tok @tc_5 cmyk2rgb rgb2hsb 3 1 roll 4 1 roll 5 1 roll @dlt_hsb}{$frt dup $frc $frm $fry $frk @tc_5 5 copy $tot dup $toc $tom $toy $tok @tc_5 5 1 roll 6 1 roll 7 1 roll 8 1 roll 9 1 roll @dlt_cmyk}ifelse}bd/@ffnxt{/$fi $fi 1 add def $frb dup 1 eq exch 2 eq or{pop pop pop pop myh mys myb $fi $fco lt{kdb add 3 1 roll kds add 3 1 roll kdh add 3 1 roll}{kdb2 add 3 1 roll kds2 add 3 1 roll kdh2 add 3 1 roll}ifelse 3 copy /myb xd/mys xd/myh xd hsb2rgb rgb2cmyk}{$fi $fco lt $fmp 50 eq or{$dk add 5 1 roll $dy add 5 1 roll $dm add 5 1 roll $dc add 5 1 roll $dt add 5 1 roll}{$dk2 add 5 1 roll $dy2 add 5 1 roll $dm2 add 5 1 roll $dc2 add 5 1 roll $dt2 add 5 1 roll}ifelse}ifelse}bd/ffcol{5 copy $fsit 0 eq{setcmykcolor pop}{SepMode_5 0 ne {$frn findcmykcustomcolor exch setcustomcolor}{pop pop pop pop $frc $frm $fry $frk $frn findcmykcustomcolor exch setcustomcolor}ifelse}ifelse}bd/@ftl{1 index 4 index sub dup $pad mul dup/$pdw xd 2 mul sub $fst div/$wid xd 2 index sub /$hei xd pop Tl @dlt $fss 0 eq{ffcol n 0 0 m 0 $hei l $pdw $hei l $pdw 0 l @cp $ffpnt{fill}{@np}ifelse}if $fss $wid mul $pdw add 0 Tl nff{ffcol n 0 0 m 0 $hei l $wid $hei l $wid 0 l @cp $ffpnt{fill}{@np}ifelse $wid 0 Tl @ffnxt}repeat 5 rp $tot dup $toc $tom $toy $tok @tc_5 ffcol n 0 0 m 0 $hei l $pdw $hei l $pdw 0 l @cp $ffpnt{fill}{@np}ifelse 5 rp}bd/@ftrs{1 index 4 index sub dup $rox mul /$row xd 2 div 1 index 4 index sub dup $roy mul/$roh xd 2 div 2 copy dup mul exch dup mul add sqrt $row dup mul $roh dup mul add sqrt add dup/$hei xd $fst div/$wid xd 4 index add $roh add exch 5 index add $row add exch Tl $fan rotate pop pop pop pop @dlt $fss 0 eq{ffcol $fty 3 eq{$hei dup neg dup m 2 mul @sqr}{ 0 0 m 0 0 $hei 0 360 arc}ifelse $ffpnt{fill}{@np}ifelse}if 1.0 $pad 2 mul sub dup scale $hei $fss $wid mul sub/$hei xd nff{ffcol $fty 3 eq{n $hei dup neg dup m 2 mul @sqr}{n 0 0 m 0 0 $hei 0 360 arc}ifelse $ffpnt{fill}{@np}ifelse/$hei $hei $wid sub def @ffnxt}repeat 5 rp}bd/@ftc{1 index 4 index sub dup $rox mul /$row xd 2 div 1 index 4 index sub dup $roy mul/$roh xd 2 div 2 copy dup mul exch dup mul add sqrt $row dup mul $roh dup mul add sqrt add dup/$hei xd $fst div/$wid xd 4 index add $roh add exch 5 index add $row add exch Tl pop pop pop pop @dlt $fss 0 eq{ffcol $ffpnt{fill}{@np}ifelse}{n}ifelse/$dang 180 $fst 1 sub div def/$sang $dang -2 div 180 add def/$eang $dang 2 div 180 add def/$sang $sang $dang $fss mul add def/$eang $eang $dang $fss mul add def/$sang $eang $dang sub def nff{ffcol n 0 0 m 0 0 $hei $sang $fan add $eang $fan add arc $ffpnt{fill}{@np}ifelse 0 0 m 0 0 $hei $eang neg $fan add $sang neg $fan add arc $ffpnt{fill}{@np}ifelse/$sang $eang def/$eang $eang $dang add def @ffnxt} repeat 5 rp}bd/@fstAdjust{72 0 matrix defaultmatrix dtransform exch dup mul exch dup mul add sqrt currentscreen pop pop div dup mul 1 add cvi 2 256 InRange $fsc 1 sub dup 0 le{pop 1}if mul/opt$fst xd AutoSteps dup 1 eq exch 3 eq or{ opt$fst dup dup $fst dup 3 1 roll div exch 3 -1 roll gt{/$adj xd/$fst xd}{pop pop}ifelse}if AutoSteps dup 2 eq exch 3 eq or{opt$fst dup dup $fst dup 3 1 roll div exch 3 -1 roll lt{/$adj xd/$fst xd}{pop pop}ifelse}if}bd/@ff{/old$fst $fst def/$adj 1 def/$fss 0 def $o 1 eq setoverprint AutoSteps 0 gt{@fstAdjust}if 1 1 $fsc 1 sub{dup 1 sub $fsit 0 eq{$fsa exch 5 mul 5 getinterval aload pop pop /$frk xd/$fry xd/$frm xd/$frc xd/$frn _ def/$frt 1 def $fsa exch 5 mul 5 getinterval aload pop $adj mul cvi $fss add/$fse xd/$tok xd/$toy xd/$tom xd /$toc xd/$ton _ def/$tot 1 def}{$fsa exch 7 mul 7 getinterval aload pop pop /$frt xd/$frn xd/$frk xd/$fry xd/$frm xd/$frc xd $fsa exch 7 mul 7 getinterval aload pop $adj mul cvi $fss add/$fse xd/$tot xd/$ton xd/$tok xd/$toy xd/$tom xd /$toc xd}ifelse $fsit 0 eq SepMode_5 0 eq or dup not CurrentInkName_5 $frn eq and or{@sv $ctm setmatrix eoclip Bbllx Bblly Bburx Bbury $fty 2 eq{@ftc}{1 index 3 index m 2 copy l 3 index 1 index l 3 index 3 index l @cp $fty dup 1 eq exch 3 eq or{@ftrs}{pop pop pop pop $fan rotate pathbbox @ftl}ifelse}ifelse @rs /$fss $fse def}{1 0 0 0 0 _ $o @scc_5{fill}if}ifelse}for @np/$fst old$fst def} bd/@Pf{@sv SepMode_5 0 eq $Psc 0 ne or $ink_5 3 eq or{0 J 0 j[]0 d $t $c $m $y $k $n $o @scc_5 pop $ctm setmatrix 72 1000 div dup matrix scale dup concat dup Bburx exch Bbury exch itransform ceiling cvi/Bbury xd ceiling cvi/Bburx xd Bbllx exch Bblly exch itransform floor cvi/Bblly xd floor cvi/Bbllx xd $Prm aload pop $Psn load exec}{1 SetGry eofill}ifelse @rs @np}bd/F{matrix currentmatrix $sdf{$scf $sca $scp @ss}if $fil 1 eq{@pf}{$fil 2 eq{@ff}{$fil 3 eq{@Pf}{$t $c $m $y $k $n $o @scc_5{eofill}{@np}ifelse}ifelse}ifelse}ifelse $sdf{$dsf $dsa $dsp @ss}if setmatrix}bd/f{@cp F}bd/S{matrix currentmatrix $ctm setmatrix $SDF{$SCF $SCA $SCP @ss}if $T $C $M $Y $K $N $O @scc_5{matrix currentmatrix $ptm concat stroke setmatrix}{@np}ifelse $SDF{$dsf $dsa $dsp @ss}if setmatrix}bd/s{@cp S}bd/B{@gs F @gr S}bd/b{@cp B}bd/_E{5 array astore exch cvlit xd}bd/@cc{currentfile $dat readhexstring pop}bd/@sm{/$ctm $ctm currentmatrix def}bd/@E{/Bbury xd/Bburx xd/Bblly xd/Bbllx xd}bd/@c{@cp}bd/@p{ /$fil 1 def 1 eq dup/$vectpat xd{/$pfrg true def}{@gs $t $c $m $y $k $n $o @scc_5/$pfrg xd @gr}ifelse/$pm xd/$psy xd/$psx xd/$pyf xd/$pxf xd/$pn xd}bd/@P {/$fil 3 def/$Psn xd/$Psc xd array astore/$Prm xd}bd/@k{/$fil 2 def/$fmp xd /$roy xd/$rox xd/$pad xd/$fty xd/$fan xd $fty 1 eq{/$fan 0 def}if/$frb xd/$fst xd/$fsc xd/$fsa xd/$fsit 0 def}bd/@x{/$fil 2 def/$fmp xd/$roy xd/$rox xd/$pad xd/$fty xd/$fan xd $fty 1 eq{/$fan 0 def}if/$frb xd/$fst xd/$fsc xd/$fsa xd /$fsit 1 def}bd/@ii{concat 3 index 3 index m 3 index 1 index l 2 copy l 1 index 3 index l 3 index 3 index l clip pop pop pop pop}bd/tcc{@cc}def/@i{@sm @gs @ii 6 index 1 ne{/$frg true def pop pop}{1 eq{s1t s1c s1m s1y s1k s1n $O @scc_5 /$frg xd}{/$frg false def}ifelse 1 eq{@gs $ctm setmatrix F @gr}if}ifelse @np /$ury xd/$urx xd/$lly xd/$llx xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul 8 div ceiling cvi string def $bkg $frg or{$SDF{$SCF $SCA $SCP @ss}if $llx $lly Tl $urx $llx sub $ury $lly sub scale $bkg{$t $c $m $y $k $n $o @scc_5 pop}if $wid $hei abs $bts 1 eq{$bkg}{$bts}ifelse[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/tcc load $bts 1 eq{imagemask}{image}ifelse $SDF{$dsf $dsa $dsp @ss}if}{$hei abs{tcc pop}repeat}ifelse @gr $ctm setmatrix}bd/@I{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd/$llx xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div ceiling cvi string def $ngx $llx $lly Tl $urx $llx sub $ury $lly sub scale $wid $hei abs $bts[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/@cc load false $ncl ColorImage $SDF{$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd L2?{/@I_2{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd/$llx xd /$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div ceiling cvi string def $ngx $ncl 1 eq{/DeviceGray}{$ncl 3 eq{/DeviceRGB}{/DeviceCMYK} ifelse}ifelse setcolorspace $llx $lly Tl $urx $llx sub $ury $lly sub scale 8 dict begin/ImageType 1 def/Width $wid def/Height $hei abs def/BitsPerComponent $bts def/Decode $ncl 1 eq{[0 1]}{$ncl 3 eq{[0 1 0 1 0 1]}{[0 1 0 1 0 1 0 1]} ifelse}ifelse def/ImageMatrix[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]def /DataSource currentfile/ASCII85Decode filter def currentdict end image $SDF {$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd}{/@I_2{}bd}ifelse/z{exch findfont exch scalefont setfont}bd/ZB{9 dict dup begin 4 1 roll/FontType 3 def /FontMatrix xd/FontBBox xd/Encoding 256 array def 0 1 255{Encoding exch /.notdef put}for/CharStrings 256 dict def CharStrings/.notdef{}put/Metrics 256 dict def Metrics/.notdef 3 -1 roll put/BuildChar{exch dup/$char exch/Encoding get 3 index get def dup/Metrics get $char get aload pop setcachedevice begin Encoding exch get CharStrings exch get end exec}def end definefont pop}bd /ZBAddChar{findfont begin dup 4 1 roll dup 6 1 roll Encoding 3 1 roll put CharStrings 3 1 roll put Metrics 3 1 roll put end}bd/Z{findfont dup maxlength 2 add dict exch dup{1 index/FID ne{3 index 3 1 roll put}{pop pop}ifelse}forall pop dup dup/Encoding get 256 array copy dup/$fe xd/Encoding exch put dup /Fontname 3 index put 3 -1 roll dup length 0 ne{0 exch{dup type 0 type eq{exch pop}{$fe exch 2 index exch put 1 add}ifelse}forall pop}if dup 256 dict dup /$met xd/Metrics exch put dup/FontMatrix get 0 get 1000 mul 1 exch div 3 index length 256 eq{0 1 255{dup $fe exch get dup/.notdef eq{pop pop}{5 index 3 -1 roll get 2 index mul $met 3 1 roll put}ifelse}for}if pop definefont pop pop}bd /@ftx{{currentpoint 3 -1 roll(0)dup 3 -1 roll 0 exch put dup @gs true charpath $ctm setmatrix @@txt @gr @np stringwidth pop 3 -1 roll add exch m}forall}bd /@ft{matrix currentmatrix exch $sdf{$scf $sca $scp @ss}if $fil 1 eq{/@@txt/@pf ld @ftx}{$fil 2 eq{/@@txt/@ff ld @ftx}{$fil 3 eq{/@@txt/@Pf ld @ftx}{$t $c $m $y $k $n $o @scc_5{show}{pop}ifelse}ifelse}ifelse}ifelse $sdf{$dsf $dsa $dsp @ss}if setmatrix}bd/@st{matrix currentmatrix exch $SDF{$SCF $SCA $SCP @ss}if $T $C $M $Y $K $N $O @scc_5{{currentpoint 3 -1 roll(0)dup 3 -1 roll 0 exch put dup @gs true charpath $ctm setmatrix $ptm concat stroke @gr @np stringwidth pop 3 -1 roll add exch m}forall}{pop}ifelse $SDF{$dsf $dsa $dsp @ss}if setmatrix}bd /@te{@ft}bd/@tr{@st}bd/@ta{dup @gs @ft @gr @st}bd/@t@a{dup @gs @st @gr @ft}bd /@tm{@sm concat}bd/e{/t{@te}def}bd/r{/t{@tr}def}bd/o{/t{pop}def}bd/a{/t{@ta} def}bd/@a{/t{@t@a}def}bd/t{@te}def/T{@np $ctm setmatrix/$ttm matrix def}bd/ddt {t}def/@t{/$stm $stm currentmatrix def 3 1 roll m $ttm concat ddt $stm setmatrix}bd/@n{/$ttm exch matrix rotate def}bd/@s{}bd/@l{}bd/@B{@gs S @gr F} bd/@b{@cp @B}bd/@sep{CurrentInkName_5(Composite)eq{/$ink_5 -1 def}{ CurrentInkName_5(Cyan)eq{/$ink_5 0 def}{CurrentInkName_5(Magenta)eq{/$ink_5 1 def}{CurrentInkName_5(Yellow)eq{/$ink_5 2 def}{CurrentInkName_5(Black)eq {/$ink_5 3 def}{/$ink_5 4 def}ifelse}ifelse}ifelse}ifelse}ifelse}bd/@whi{@gs -72000 dup m -72000 72000 l 72000 dup l 72000 -72000 l @cp 1 SetGry fill @gr} bd/@neg{[{1 exch sub}/exec cvx currenttransfer/exec cvx]cvx settransfer @whi} bd/currentscale{1 0 dtransform matrix defaultmatrix idtransform dup mul exch dup mul add sqrt 0 1 dtransform matrix defaultmatrix idtransform dup mul exch dup mul add sqrt}bd/@unscale{}bd/@smc{CMYKMarks{0 exch eq{1 1 1 1 1 _ 0 @scc_5 pop}{1 0 0 0 0 _ 0 @scc_5 pop}ifelse}{SetGry}ifelse}bd/@gmc{CMYKMarks{GetCmyk pop pop pop 1 eq{0}{1}ifelse}{GetGry}ifelse}bd/@sqr{dup 0 rl dup 0 exch rl neg 0 rl @cp}bd/corelsym{@gs @np Tl -90 rotate 7{45 rotate -.75 2 m 1.5 @sqr fill} repeat @gr}bd/@reg_cor{@gs @np Tl -6 -6 m 12 @sqr @gs 1 @gmc sub @smc fill @gr 4{90 rotate 0 4 m 0 4 rl}repeat stroke 0 0 corelsym @gr}bd/@reg_std{@gs @np Tl .3 w 0 0 5 0 360 arc @cp @gs 1 @gmc sub @smc fill @gr 4{90 rotate 0 0 m 0 8 rl }repeat stroke @gr}bd/@reg_inv{@gs @np Tl .3 w 0 0 5 0 360 arc @cp @gs 1 @gmc sub @smc fill @gr 4{90 rotate 0 0 m 0 8 rl}repeat stroke 0 0 m 0 0 5 90 180 arc @cp 0 0 5 270 360 arc @cp fill @gr}bd/@reg_sqr{@gs @np Tl .3 w -7 -7 m 14 @sqr fill @gs 1 @gmc sub @smc 0 0 5 0 360 arc @cp save fill restore 4{90 rotate 0 0 m 0 8 rl}repeat stroke @gr 4{90 rotate 0 0 m 0 5 rl}repeat stroke @gr}bd /@reg_lng{@gs @np 0 eq{/$Xlen 16 def/$Ylen 8 def}{/$Xlen 8 def/$Ylen 16 def} ifelse Tl .3 w 0 0 5 0 360 arc @cp @gs 1 @gmc sub @smc fill @gr 90 rotate 0 0 m 0 $Xlen rl 90 rotate 0 0 m 0 $Ylen rl 90 rotate 0 0 m 0 $Xlen rl 90 rotate 0 0 m 0 $Ylen rl stroke @gr}bd/@setdcol{0 $dcol eq{0 exch 1 exch sub 0 0 0 _ 0 @scc_5 pop}{1 $dcol eq{0 exch 0 exch 1 exch sub 0 0 _ 0 @scc_5 pop}{2 $dcol eq {0 exch 0 exch 0 exch 1 exch sub 0 _ 0 @scc_5 pop}{SetGry}ifelse}ifelse}ifelse }bd/$corelmeter[1 .95 .75 .50 .25 .05 0]def/@colormeter{@gs @np 0 @setdcol 0.3 w/Courier findfont 5 scalefont setfont/yy xd/xx xd 0 1 6{dup xx 20 sub yy m 20 @sqr @gs $corelmeter exch get dup @setdcol fill @gr stroke xx 18 sub yy 2 add m exch dup 3 ge{1 SetGry}{0 @setdcol}ifelse 3 eq{pop}{100 mul 100 exch sub cvi 20 string cvs show}ifelse/yy yy 20 add def}for @gr}bd/@calbar{@gs Tl @gs @np 0 0 m @gs 20 @sqr 1 1 0 0 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 1 0 1 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 0 0 1 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 0 1 1 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 0 1 0 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 1 1 0 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 1 1 1 0 _ 0 @scc_5 pop fill @gr @gr @np -84 0 Tl @gs 0 0 m 20 @sqr clip 1 1 0 0 0 _ 0 @scc_5 pop @gain @gr 20 0 Tl @gs 0 0 m 20 @sqr clip 1 0 1 0 0 _ 0 @scc_5 pop @gain @gr 20 0 Tl @gs 0 0 m 20 @sqr clip 1 0 0 1 0 _ 0 @scc_5 pop @gain @gr 20 0 Tl @gs 0 0 m 20 @sqr clip 1 0 0 0 1 _ 0 @scc_5 pop @gain @gr @gr}bd/@gain{10 10 Tl @np 0 0 m 0 10 360{0 0 15 4 -1 roll dup 5 add arc @cp}for fill}bd/@crop{@gs 10 div /$croplen xd .3 w 0 @smc Tl rotate 0 0 m 0 $croplen neg rl stroke @gr}bd /deflevel 0 def/@sax{/deflevel deflevel 1 add def}bd/@eax{/deflevel deflevel dup 0 gt{1 sub}if def deflevel 0 gt{/eax load}{eax}ifelse}bd/eax{{exec}forall} bd/@rax{deflevel 0 eq{@rs @sv}if}bd/@daq{dup type/arraytype eq{{}forall}if}bd /@BMP{/@cc xd 12 index 1 gt UseLevel2 true eq and{7 -2 roll pop pop @I_2}{11 index 1 eq{12 -1 roll pop @i}{7 -2 roll pop pop @I}ifelse}ifelse}bd systemdict /pdfmark known not{/pdfmark/cleartomark ld}if/@BeginEPS{$ngx 0 SetGry 0 J 0 j 1 w[]0 d 10 M false setoverprint @np/EPSDict 200 dict def EPSDict begin @sv SepMode_5 0 ne{/colorimage{@gs/sepdict 50 dict def sepdict begin[{1 exch sub} /exec cvx currenttransfer/exec cvx]cvx settransfer 3 eq/$rgb xd{$rgb{/daq0 xd /daq1 xd/daq2 xd/daq_rgb load}{/daq0 xd/daq1 xd/daq2 xd/daq3 xd/daq_cmyk load} ifelse}{/daq0 xd/daq_one load}ifelse 2 index 8 eq/8bit xd $ink_5 dup 0 lt exch 3 gt or{}{image}ifelse end @gr}bd/2cmyk{3{255 exch sub 3 1 roll}repeat 3 copy @MN @MN 3{dup 5 -1 roll sub neg exch}repeat}bd/daq_rgb{/i 0 def/daq2 load exec /daq1 load exec/daq0 load exec dup dup length 0 exch getinterval/$data xd{8bit {1 index i get 3 index i get 2cmyk 4 $ink_5 neg roll pop pop pop}{pop 0}ifelse $data i 3 -1 roll put/i i 1 add def}forall pop pop $data}bd/daq_cmyk{/daq3 load exec/daq2 load exec/daq1 load exec/daq0 load exec 4 $ink_5 neg roll pop pop pop }bd/daq_one{/$in 0 def/$out 0 def/daq0 load exec dup dup length $rgb{3}{4} ifelse idiv 0 exch getinterval/$data xd $data{pop 8bit{$rgb{0 index $in 2 add get 1 index $in 1 add get 2 index $in get 2cmyk}{0 index $in get 1 index $in 1 add get 2 index $in 2 add get 3 index $in 3 add get}ifelse 4 $ink_5 neg roll pop pop pop}{0}ifelse $data $out 3 -1 roll put/$in $in $rgb{3}{4}ifelse add def /$out $out 1 add def}forall pop $data}bd}if}bd/@EndEPS{@rs end}bd end %%EndResource %%EndProlog %%BeginSetup wCorel6Dict begin @BeginSysCorelDict 2.6131 setmiterlimit 1.00 setflat /$fst 128 def %%EndSetup %%Page: 1 1 %LogicalPage: 1 %%BeginPageSetup @sv @sm @sv %%EndPageSetup @rax 94.00252 695.44091 98.57055 707.88501 @E [0.00028346 0.00000000 0.00000000 0.00028346 94.00251625 695.44088795] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (:) @t 7645 35431 m 7645 43900 L 16115 43900 L 16115 35420 L 7645 35431 L @c 7645 0 m 7645 8470 L 16115 8470 L 16115 0 L 7645 0 L @c F T @rax %Note: Object 79.22183 684.59811 113.35153 718.72781 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 96.28668 718.72781 m 105.68580 718.72781 113.35153 711.06208 113.35153 701.66296 c 113.35153 692.26384 105.68580 684.59811 96.28668 684.59811 c 86.88756 684.59811 79.22183 692.26384 79.22183 701.66296 c 79.22183 711.06208 86.88756 718.72781 96.28668 718.72781 c @c S @rax 167.79118 609.00038 172.35921 621.44447 @E [0.00028346 0.00000000 0.00000000 0.00028346 167.79117496 609.00035568] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (:) @t 7645 35431 m 7645 43900 L 16115 43900 L 16115 35420 L 7645 35431 L @c 7645 0 m 7645 8470 L 16115 8470 L 16115 0 L 7645 0 L @c F T @rax %Note: Object 153.01049 598.15757 187.14019 632.28728 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 170.07534 632.28728 m 179.47446 632.28728 187.14019 624.62154 187.14019 615.22243 c 187.14019 605.82331 179.47446 598.15757 170.07534 598.15757 c 160.67622 598.15757 153.01049 605.82331 153.01049 615.22243 c 153.01049 624.62154 160.67622 632.28728 170.07534 632.28728 c @c S @rax 244.86180 525.20372 257.53975 539.33471 @E [0.00028346 0.00000000 0.00000000 0.00028346 244.86178632 525.20369732] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (+) @t 21208 9801 m 21208 26411 L 4708 26411 L 4708 33352 L 21208 33352 L 21208 49851 L 28226 49851 L 28226 33352 L 44725 33352 L 44725 26411 L 28226 26411 L 28226 9790 L 21208 9801 L @c F T @rax %Note: Object 234.13606 515.20422 268.26576 549.33392 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 251.20091 549.33392 m 260.60003 549.33392 268.26576 541.66819 268.26576 532.26907 c 268.26576 522.86995 260.60003 515.20422 251.20091 515.20422 c 241.80180 515.20422 234.13606 522.86995 234.13606 532.26907 c 234.13606 541.66819 241.80180 549.33392 251.20091 549.33392 c @c S @rax 80.87613 756.63156 105.23764 774.38580 @E [0.00028346 0.00000000 0.00000000 0.00028346 80.87612303 756.91527940] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (f) @t 7359 0 m 7348 38115 L 781 38115 L 781 43900 L 7348 43900 L 7348 48575 l 7348 51523 7612 53712 8140 55142 c 8855 57067 10120 58640 11924 59828 c 13728 61027 16258 61632 19503 61632 c 21593 61632 23925 61379 26455 60884 C 25333 54394 L 23793 54669 22330 54812 20955 54812 c 18700 54812 17094 54328 16159 53371 c 15224 52403 14751 50588 14751 47948 c 14751 43900 L 23309 43900 L 23309 38115 L 14751 38115 L 14751 0 L 7359 0 L @c F %CHAR: 23518 0 (i) @t 29139 52051 m 29139 60598 L 36575 60598 L 36575 52040 L 29139 52051 L @c 29139 0 m 29139 43900 L 36575 43900 L 36575 0 L 29139 0 L @c F %CHAR: 42328 0 (b) @t 54769 0 m 47861 0 L 47861 60598 L 55308 60598 L 55308 38984 L 58443 42921 62458 44890 67331 44890 c 70037 44890 72600 44340 74998 43262 c 77407 42174 79398 40634 80949 38676 c 82511 36707 83732 34320 84612 31548 c 85491 28765 85942 25773 85942 22605 c 85942 15081 84084 9262 80366 5159 c 76648 1056 72171 -1001 66957 -1001 c 61787 -1001 57717 1166 54769 5489 C 54769 0 L @c 54692 22286 m 54692 17017 55407 13200 56837 10868 c 59169 7040 62348 5126 66341 5126 c 69597 5126 72413 6545 74778 9361 c 77143 12177 78331 16401 78331 21989 c 78331 27720 77187 31955 74921 34683 c 72655 37411 69894 38775 66671 38775 c 63426 38775 60610 37356 58245 34540 c 55869 31713 54681 27621 54681 22275 C 54692 22286 L @c F T @rax 35.58813 658.42384 44.53087 675.67294 @E [0.00028346 0.00000000 0.00000000 0.00028346 35.58812468 658.42381843] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (1) @t 31548 0 m 24101 0 L 24101 47409 L 22308 45704 19954 43988 17050 42284 c 14146 40579 11528 39292 9218 38445 C 9218 45638 L 13376 47596 17017 49972 20119 52744 c 23232 55527 25443 58233 26741 60851 C 31537 60851 L 31548 0 L @c F T @rax 103.19102 556.62718 112.13376 573.87628 @E [0.00028346 0.00000000 0.00000000 0.00028346 103.19101985 556.62716074] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (1) @t 31548 0 m 24101 0 L 24101 47409 L 22308 45704 19954 43988 17050 42284 c 14146 40579 11528 39292 9218 38445 C 9218 45638 L 13376 47596 17017 49972 20119 52744 c 23232 55527 25443 58233 26741 60851 C 31537 60851 L 31548 0 L @c F T @rax %Note: Object 95.31439 719.89824 95.31553 750.96624 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 95.31496 719.89824 m 95.31496 739.26964 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01600 2.01600 0 @w 95.31496 750.96624 m 89.14592 738.62419 L 101.48797 738.62419 L 95.31496 750.96624 L f @J @rax %Note: Object 108.72057 630.15250 159.25861 688.32255 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 159.25861 630.15250 m 116.36901 679.51899 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01005 2.01005 0 @w 108.72057 688.32255 m 112.14794 674.99915 L 121.43735 683.06995 L 108.72057 688.32255 L f @J @rax %Note: Object 54.90085 669.15269 81.81071 690.96643 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 54.90085 669.15269 m 72.75373 683.62469 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.00948 2.00948 0 @w 81.81071 690.96643 m 68.38214 687.99628 L 76.12866 678.43984 L 81.81071 690.96643 L f @J @rax %Note: Object 122.12617 568.83033 157.56831 603.86428 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 122.12617 568.83033 m 149.27443 595.66592 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01005 2.01005 0 @w 157.56831 603.86428 m 144.49266 599.58794 L 153.14343 590.83625 L 157.56831 603.86428 L f @J @rax %Note: Object 182.13194 544.52523 233.32620 602.03395 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 233.32620 544.52523 m 189.89943 593.30863 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01345 2.01345 0 @w 182.13194 602.03395 m 185.72598 588.73039 L 194.93263 596.92649 L 182.13194 602.03395 L f @J @rax %Note: Object 183.92060 499.14170 332.79846 648.50882 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 183.92060 628.67792 m 202.01528 648.50882 242.91609 644.27414 271.87058 633.96652 c 309.30350 620.64085 332.79846 572.37477 327.44920 540.21855 c 323.69102 517.62671 307.77761 499.14170 271.87030 516.30520 C S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.00778 2.00778 0 @w 261.36028 521.32876 m 269.80044 510.48482 L 275.10151 521.57452 L 261.36028 521.32876 L f @J @rax %Note: Object 110.41087 451.28608 480.20145 750.26041 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 110.41087 714.61020 m 150.43096 737.08469 180.48047 750.26041 242.99150 743.69509 c 347.09272 732.76186 480.20145 639.82630 422.82850 511.01717 c 397.14066 453.34517 297.70526 451.28608 232.48998 477.96633 C 206.13260 488.97524 210.11216 513.65679 225.92665 524.23739 C S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.00948 2.00948 0 @w 235.61688 530.72050 m 221.97288 528.99052 L 228.81373 518.76567 L 235.61688 530.72050 L f @J @rax 148.47874 746.90646 326.48230 767.55430 @E [0.00028346 0.00000000 0.00000000 0.00028346 148.47873473 750.30516940] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (1) @t 31548 0 m 24101 0 L 24101 47409 L 22308 45704 19954 43988 17050 42284 c 14146 40579 11528 39292 9218 38445 C 9218 45638 L 13376 47596 17017 49972 20119 52744 c 23232 55527 25443 58233 26741 60851 C 31537 60851 L 31548 0 L @c F %CHAR: 47091 0 (,) @t 54615 0 m 54615 8470 L 63085 8470 L 63085 0 l 63085 -3113 62535 -5632 61435 -7546 c 60335 -9460 58575 -10956 56177 -11990 C 54109 -8811 L 55682 -8129 56848 -7106 57585 -5775 c 58333 -4433 58751 -2508 58828 0 C 54615 0 L @c F %CHAR: 94127 0 (1) @t 125675 0 m 118228 0 L 118228 47409 L 116435 45704 114081 43988 111177 42284 c 108273 40579 105655 39292 103345 38445 C 103345 45638 L 107503 47596 111144 49972 114246 52744 c 117359 55527 119570 58233 120868 60851 C 125664 60851 L 125675 0 L @c F %CHAR: 141218 0 (,) @t 148742 0 m 148742 8470 L 157212 8470 L 157212 0 l 157212 -3113 156662 -5632 155562 -7546 c 154462 -9460 152702 -10956 150304 -11990 C 148236 -8811 L 149809 -8129 150975 -7106 151712 -5775 c 152460 -4433 152878 -2508 152955 0 C 148742 0 L @c F %CHAR: 188254 0 (2) @t 230878 7150 m 230867 0 L 190817 0 L 190762 1782 191048 3509 191675 5159 c 192698 7887 194337 10582 196581 13222 c 198825 15862 202070 18931 206316 22407 c 212894 27797 217360 32087 219670 35233 c 221980 38390 223146 41382 223146 44186 c 223146 47134 222090 49620 219978 51644 c 217866 53668 215116 54691 211728 54691 c 208153 54691 205282 53613 203137 51468 c 200981 49312 199892 46331 199870 42536 C 192214 43317 L 192742 49015 194722 53371 198132 56363 c 201542 59355 206140 60851 211893 60851 c 217701 60851 222310 59234 225698 56011 c 229086 52788 230790 48784 230790 44021 c 230790 41602 230296 39204 229306 36872 c 228316 34529 226655 32054 224367 29469 c 222068 26884 218229 23320 212883 18810 c 208428 15059 205557 12507 204292 11176 c 203027 9845 201971 8492 201146 7150 C 230878 7150 L @c F %CHAR: 235345 0 (,) @t 242869 0 m 242869 8470 L 251339 8470 L 251339 0 l 251339 -3113 250789 -5632 249689 -7546 c 248589 -9460 246829 -10956 244431 -11990 C 242363 -8811 L 243936 -8129 245102 -7106 245839 -5775 c 246587 -4433 247005 -2508 247082 0 C 242869 0 L @c F %CHAR: 282381 0 (3) @t 285934 15994 m 293370 16984 L 294228 12771 295691 9724 297737 7876 c 299783 6017 302291 5082 305239 5082 c 308737 5082 311696 6292 314105 8712 c 316514 11132 317724 14146 317724 17732 c 317724 21142 316602 23969 314380 26180 c 312147 28402 309298 29513 305855 29513 c 304458 29513 302698 29238 300608 28688 C 301433 35222 L 301928 35167 302335 35134 302632 35134 c 305800 35134 308660 35959 311190 37609 c 313720 39259 314996 41822 314996 45264 c 314996 47992 314072 50258 312224 52040 c 310376 53822 307989 54724 305074 54724 c 302181 54724 299761 53811 297836 51996 c 295911 50181 294668 47442 294118 43812 C 286671 45143 L 287573 50126 289652 53998 292875 56737 c 296098 59476 300113 60851 304909 60851 c 308209 60851 311267 60136 314039 58728 c 316822 57309 318956 55362 320430 52920 c 321904 50467 322641 47849 322641 45099 c 322641 42481 321937 40095 320540 37950 c 319132 35794 317042 34078 314292 32824 C 317867 31999 320661 30272 322641 27676 c 324621 25080 325621 21813 325621 17897 c 325621 12606 323686 8118 319836 4444 c 315975 770 311091 -1078 305195 -1078 c 299882 -1078 295460 506 291951 3674 c 288431 6842 286418 10956 285934 15994 C @c F %CHAR: 329472 0 (,) @t 336996 0 m 336996 8470 L 345466 8470 L 345466 0 l 345466 -3113 344916 -5632 343816 -7546 c 342716 -9460 340956 -10956 338558 -11990 C 336490 -8811 L 338063 -8129 339229 -7106 339966 -5775 c 340714 -4433 341132 -2508 341209 0 C 336996 0 L @c F %CHAR: 376508 0 (5) @t 380017 15873 m 387827 16533 L 388399 12727 389752 9867 391853 7953 c 393965 6039 396517 5082 399487 5082 c 403073 5082 406109 6435 408584 9130 c 411059 11825 412302 15411 412302 19877 c 412302 24123 411103 27478 408727 29920 c 406351 32373 403216 33605 399366 33605 c 396968 33605 394801 33055 392876 31977 c 390951 30888 389422 29469 388322 27731 C 381337 28644 L 387211 59773 L 417351 59773 L 417351 52667 L 393162 52667 L 389895 36377 L 393525 38907 397353 40183 401346 40183 c 406637 40183 411114 38346 414744 34683 c 418374 31020 420199 26301 420199 20537 c 420199 15059 418594 10307 415404 6325 c 411521 1419 406208 -1034 399487 -1034 c 393976 -1034 389466 506 385990 3586 c 382514 6666 380512 10769 380017 15873 C @c F %CHAR: 423599 0 (,) @t 431123 0 m 431123 8470 L 439593 8470 L 439593 0 l 439593 -3113 439043 -5632 437943 -7546 c 436843 -9460 435083 -10956 432685 -11990 C 430617 -8811 L 432190 -8129 433356 -7106 434093 -5775 c 434841 -4433 435259 -2508 435336 0 C 431123 0 L @c F %CHAR: 470635 0 (8) @t 485595 32868 m 482515 33990 480216 35607 478731 37697 c 477246 39787 476498 42306 476498 45220 c 476498 49620 478082 53338 481250 56341 c 484418 59344 488642 60851 493900 60851 c 499191 60851 503459 59311 506671 56242 c 509894 53173 511511 49422 511511 45011 c 511511 42207 510774 39754 509300 37675 c 507826 35596 505582 33979 502590 32857 C 506308 31647 509146 29689 511082 26994 c 513017 24288 513996 21054 513996 17314 c 513996 12144 512160 7777 508497 4257 c 504834 737 500005 -1034 494032 -1034 c 488048 -1034 483219 737 479556 4268 c 475893 7810 474056 12232 474056 17523 c 474056 21461 475057 24761 477048 27423 c 479050 30085 481899 31900 485595 32857 C 485595 32868 L @c 484110 45473 m 484110 42613 485034 40260 486871 38445 c 488719 36630 491117 35717 494065 35717 c 496925 35717 499290 36619 501116 38423 c 502942 40227 503866 42437 503866 45055 c 503866 47783 502920 50082 501039 51930 c 499147 53789 496793 54724 493988 54724 c 491150 54724 488796 53811 486926 51996 c 485056 50181 484110 48003 484110 45473 c @c 481712 17490 m 481712 15367 482218 13310 483219 11330 c 484220 9350 485716 7799 487696 6721 c 489676 5632 491821 5082 494109 5082 c 497662 5082 500599 6226 502909 8514 c 505219 10802 506385 13717 506385 17237 c 506385 20812 505186 23782 502810 26114 c 500434 28457 497442 29634 493867 29634 c 490369 29634 487454 28479 485166 26169 c 482867 23859 481712 20955 481712 17479 C 481712 17490 L @c F %CHAR: 517726 0 (,) @t 525250 0 m 525250 8470 L 533720 8470 L 533720 0 l 533720 -3113 533170 -5632 532070 -7546 c 530970 -9460 529210 -10956 526812 -11990 C 524744 -8811 L 526317 -8129 527483 -7106 528220 -5775 c 528968 -4433 529386 -2508 529463 0 C 525250 0 L @c F %CHAR: 564762 0 (.) @t 572451 0 m 572451 8470 L 580921 8470 L 580921 0 L 572451 0 L @c F %CHAR: 588280 0 (.) @t 595969 0 m 595969 8470 L 604439 8470 L 604439 0 L 595969 0 L @c F %CHAR: 611798 0 (.) @t 619487 0 m 619487 8470 L 627957 8470 L 627957 0 L 619487 0 L @c F T @rax 170.13770 656.34690 321.45959 676.99474 @E [0.00028346 0.00000000 0.00000000 0.00028346 170.13769456 659.74561366] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 84666.00000 z %CHAR: 0 0 (1) @t 31548 0 m 24101 0 L 24101 47409 L 22308 45704 19954 43988 17050 42284 c 14146 40579 11528 39292 9218 38445 C 9218 45638 L 13376 47596 17017 49972 20119 52744 c 23232 55527 25443 58233 26741 60851 C 31537 60851 L 31548 0 L @c F %CHAR: 47091 0 (,) @t 54615 0 m 54615 8470 L 63085 8470 L 63085 0 l 63085 -3113 62535 -5632 61435 -7546 c 60335 -9460 58575 -10956 56177 -11990 C 54109 -8811 L 55682 -8129 56848 -7106 57585 -5775 c 58333 -4433 58751 -2508 58828 0 C 54615 0 L @c F %CHAR: 94127 0 (2) @t 136751 7150 m 136740 0 L 96690 0 L 96635 1782 96921 3509 97548 5159 c 98571 7887 100210 10582 102454 13222 c 104698 15862 107943 18931 112189 22407 c 118767 27797 123233 32087 125543 35233 c 127853 38390 129019 41382 129019 44186 c 129019 47134 127963 49620 125851 51644 c 123739 53668 120989 54691 117601 54691 c 114026 54691 111155 53613 109010 51468 c 106854 49312 105765 46331 105743 42536 C 98087 43317 L 98615 49015 100595 53371 104005 56363 c 107415 59355 112013 60851 117766 60851 c 123574 60851 128183 59234 131571 56011 c 134959 52788 136663 48784 136663 44021 c 136663 41602 136169 39204 135179 36872 c 134189 34529 132528 32054 130240 29469 c 127941 26884 124102 23320 118756 18810 c 114301 15059 111430 12507 110165 11176 c 108900 9845 107844 8492 107019 7150 C 136751 7150 L @c F %CHAR: 141218 0 (,) @t 148742 0 m 148742 8470 L 157212 8470 L 157212 0 l 157212 -3113 156662 -5632 155562 -7546 c 154462 -9460 152702 -10956 150304 -11990 C 148236 -8811 L 149809 -8129 150975 -7106 151712 -5775 c 152460 -4433 152878 -2508 152955 0 C 148742 0 L @c F %CHAR: 188254 0 (3) @t 191807 15994 m 199243 16984 L 200101 12771 201564 9724 203610 7876 c 205656 6017 208164 5082 211112 5082 c 214610 5082 217569 6292 219978 8712 c 222387 11132 223597 14146 223597 17732 c 223597 21142 222475 23969 220253 26180 c 218020 28402 215171 29513 211728 29513 c 210331 29513 208571 29238 206481 28688 C 207306 35222 L 207801 35167 208208 35134 208505 35134 c 211673 35134 214533 35959 217063 37609 c 219593 39259 220869 41822 220869 45264 c 220869 47992 219945 50258 218097 52040 c 216249 53822 213862 54724 210947 54724 c 208054 54724 205634 53811 203709 51996 c 201784 50181 200541 47442 199991 43812 C 192544 45143 L 193446 50126 195525 53998 198748 56737 c 201971 59476 205986 60851 210782 60851 c 214082 60851 217140 60136 219912 58728 c 222695 57309 224829 55362 226303 52920 c 227777 50467 228514 47849 228514 45099 c 228514 42481 227810 40095 226413 37950 c 225005 35794 222915 34078 220165 32824 C 223740 31999 226534 30272 228514 27676 c 230494 25080 231494 21813 231494 17897 c 231494 12606 229559 8118 225709 4444 c 221848 770 216964 -1078 211068 -1078 c 205755 -1078 201333 506 197824 3674 c 194304 6842 192291 10956 191807 15994 C @c F %CHAR: 235345 0 (,) @t 242869 0 m 242869 8470 L 251339 8470 L 251339 0 l 251339 -3113 250789 -5632 249689 -7546 c 248589 -9460 246829 -10956 244431 -11990 C 242363 -8811 L 243936 -8129 245102 -7106 245839 -5775 c 246587 -4433 247005 -2508 247082 0 C 242869 0 L @c F %CHAR: 282381 0 (5) @t 285890 15873 m 293700 16533 L 294272 12727 295625 9867 297726 7953 c 299838 6039 302390 5082 305360 5082 c 308946 5082 311982 6435 314457 9130 c 316932 11825 318175 15411 318175 19877 c 318175 24123 316976 27478 314600 29920 c 312224 32373 309089 33605 305239 33605 c 302841 33605 300674 33055 298749 31977 c 296824 30888 295295 29469 294195 27731 C 287210 28644 L 293084 59773 L 323224 59773 L 323224 52667 L 299035 52667 L 295768 36377 L 299398 38907 303226 40183 307219 40183 c 312510 40183 316987 38346 320617 34683 c 324247 31020 326072 26301 326072 20537 c 326072 15059 324467 10307 321277 6325 c 317394 1419 312081 -1034 305360 -1034 c 299849 -1034 295339 506 291863 3586 c 288387 6666 286385 10769 285890 15873 C @c F %CHAR: 329472 0 (,) @t 336996 0 m 336996 8470 L 345466 8470 L 345466 0 l 345466 -3113 344916 -5632 343816 -7546 c 342716 -9460 340956 -10956 338558 -11990 C 336490 -8811 L 338063 -8129 339229 -7106 339966 -5775 c 340714 -4433 341132 -2508 341209 0 C 336996 0 L @c F %CHAR: 376508 0 (8) @t 391468 32868 m 388388 33990 386089 35607 384604 37697 c 383119 39787 382371 42306 382371 45220 c 382371 49620 383955 53338 387123 56341 c 390291 59344 394515 60851 399773 60851 c 405064 60851 409332 59311 412544 56242 c 415767 53173 417384 49422 417384 45011 c 417384 42207 416647 39754 415173 37675 c 413699 35596 411455 33979 408463 32857 C 412181 31647 415019 29689 416955 26994 c 418890 24288 419869 21054 419869 17314 c 419869 12144 418033 7777 414370 4257 c 410707 737 405878 -1034 399905 -1034 c 393921 -1034 389092 737 385429 4268 c 381766 7810 379929 12232 379929 17523 c 379929 21461 380930 24761 382921 27423 c 384923 30085 387772 31900 391468 32857 C 391468 32868 L @c 389983 45473 m 389983 42613 390907 40260 392744 38445 c 394592 36630 396990 35717 399938 35717 c 402798 35717 405163 36619 406989 38423 c 408815 40227 409739 42437 409739 45055 c 409739 47783 408793 50082 406912 51930 c 405020 53789 402666 54724 399861 54724 c 397023 54724 394669 53811 392799 51996 c 390929 50181 389983 48003 389983 45473 c @c 387585 17490 m 387585 15367 388091 13310 389092 11330 c 390093 9350 391589 7799 393569 6721 c 395549 5632 397694 5082 399982 5082 c 403535 5082 406472 6226 408782 8514 c 411092 10802 412258 13717 412258 17237 c 412258 20812 411059 23782 408683 26114 c 406307 28457 403315 29634 399740 29634 c 396242 29634 393327 28479 391039 26169 c 388740 23859 387585 20955 387585 17479 C 387585 17490 L @c F %CHAR: 423599 0 (,) @t 431123 0 m 431123 8470 L 439593 8470 L 439593 0 l 439593 -3113 439043 -5632 437943 -7546 c 436843 -9460 435083 -10956 432685 -11990 C 430617 -8811 L 432190 -8129 433356 -7106 434093 -5775 c 434841 -4433 435259 -2508 435336 0 C 431123 0 L @c F %CHAR: 470635 0 (.) @t 478324 0 m 478324 8470 L 486794 8470 L 486794 0 L 478324 0 L @c F %CHAR: 494153 0 (.) @t 501842 0 m 501842 8470 L 510312 8470 L 510312 0 L 501842 0 L @c F %CHAR: 517671 0 (.) @t 525360 0 m 525360 8470 L 533830 8470 L 533830 0 L 525360 0 L @c F T %%PageTrailer @rs @rs %%Trailer @EndSysCorelDict end %%DocumentSuppliedResources: procset wCorel6Dict %%EOF haskell-98-tutorial-sources/fig1.gif0100644000106400000620000000630706774446522015745 0ustar jcpftpGIF87a¡E€ÿÿÿ!ù,¡EÿŒ©ËB4“V‡³Þ¼û†âH–扦jµ­òL×öçúî], ‡Ä¢‘s$̦ó Þ– ªôŠÍj·Ã–÷uH~¹ä²ùŒVx]_dŽËçt¤û2nûŠVQ¿ç—÷±6øW—È·‡Ç¸Ç‡òØáÂB‰ˆñS9©×¦jdEõ‡¹chÉycZEÚª&Iø*j[ãø°;å9¢Y›¹ËËK¹{«¬3Ú8l·¬t‚H ö }Òw½ü]ÍX¬Y¡]%&s. È ¿Ò<¾Íä==Ïβÿ˜ZOž@ôRp‚ŸŠ„¬C5 ØÀ‰ï44ÇFFcþ)6ZeïÐ?Š$Ýé #q£Fd‘ú)y7+›Ë’ ‚¸¦Î–#:šI3h•éëÉAQ¡Lµ,Å&h&©Eó=kŠõÕ“Q)M*©Ÿµ¬dA=ýd”„*_Öâ³¶µ¬\Qq¡š,ÑÌ¥›t QÎý;ôÑ[ÁÁ }´ëê°ß©ŠkŒÖêâÉ€ã¬BøG…—ÞPžæy3ã(%›R]eË8·Ô=È%^Ù«™^®æ5_ÜAG–9 üõÓà¼{·vJ›kéäÅ›¯3,Ô³áéÔ«[Ÿî<;.Èߤ_ÿ>|uíäñb·å]¼úõì¡ë._v¼¢‡íC[J—¾¾uøü-ÿÈ?£﵃~ÞÖ_e×å¶^nzˆ·[‚«}çÚƒMƒþžS bx}ã¸a`>^„%±Wb|gi4¢‚¶hÛ‹ -XœˆÔÑH‚Bì—`Š<äã)8–¨ÞÝÙwJ¸#‰OvÁ¤HÐM™Ø‘X²&åK;nYš–`’QäQŽ™”…ç¡éa—2­Éæ,gÆ)E™æ}I§Z1æÙ„^]ÉgKx Í @j&œˆ â ‹>è£9ø¦£’êc饘 ꤦ†*êiGKêb–ÚÕŸ¢j©¬¦â¨¯2#ë¬Âhe•¶ÂzÜ®jþ—¥o¾þXë¬,«ë°ÿz kl{o2«,]‘²ši”ÅF{Ä´ž^û+°ØbÆ-ŸÐò“é·!®*n¯ÈRjî=á‚9n[ê¶{n¼ðÎ »ô"„.–öVšì¾“âËã¿»)ðv·¨o '\'ÁAâ ËãøÂM\±ÄC¡-ËðÇ8„Œdël2Æ,ó6òÊ/·ì®Å9ÎL.Ít \žÍ$—¬óÉýf³ÌA'B„Eç«ñѦú<×Òä6íôÓRcuõcTWm5ÐñPzNÖ\ó‹stk#öØ}B½qÚþy­6£pkU6JuÇM¶ÛDÖÍ6ÞXÐGôÕCû ààÿªêÖ„óÐwwÝBÍóâ;ŽŽþ_PޏäËDþu€Œ½«¹‰z~dµ'†næ¡PxQ’o7ŽºË£ÿæêë¬Û­zìÃ.Gí¶{{ºî¢Ï-;ç¿«Ø:èÂï~7™Þýy¹ËÓÞ|›ÊËyýôÌŸagÉ>¯=—ÜhõÏÎ~÷›ûfþùí§OåûÒŽ{îðG,?ùö¿ã½âw…³´ÆIOfþãÂþ¶ãôù¤~çúÓƒX´Ë±Ìx+R WÀ»e= d/ㄾ<èáЂC¬;(Ø‹Xä€iI¼D¦|†,%\/P?úi-2ÿ«Š+®:&+4!‘e@ ñˆHùÅ}bCŽ )q4LL^!¨ÿC…ÜHOéÛ+pSD(N튉#cE•*XyB*¹Ù c85Õ‹häUá‘«,’NCôO練:Ά=€¡߈š—ü/"ͳ@™¸Qf¤"ÛÂH6q9@##;¹¾K&Ò[ÜäÊ~Øœ9RªŒÉ[xÆFž޳œ¤ÿøÈ¸O¢2”$ 9JzR—°Ù›(kéÊGÎð”„Þ2‡yÌ*.)šUiE餡¨NK›é˜ qÙªVjq"âdf3[§¦gn˜Až4UèlZćó)';+GL‡eò‰Ù' íIÄ|*²ŸÂhÛ JKeÂò•šLe¡YIwþVCŒƒ$hàJ·Þ/[%IG7š¨ˆâó£ å”H§ Î’Þé¤(M©JíÈÒPºô¥Ø‹©LmJӃ݋š95áL[ÚS3 k$ jMwúS£2 §tãéJ캢ө,¬Oª6T¢JõVʘD–ÕƒRõ]ÕÏÅÂZ£­ZU:Óо¶ÊJbñC÷±Ü~˜ 3¸v®£vZ_q¥,´¦5š·“[ŠðJC½în¾CB[«ÈçÍÖcå*²±V0ÄÌe;YÐ6Õšƒ‘lG>{)Ó†V0ú*:Ñó¸Ôj¶Gy˜Iµ“…Rð(-J±Áíªíj¾1ñÿvµÖlír»÷\Ú&5®ëlqu»!â.öƒ—K,f£Ý›2$ºy#ïTq‹4©™·¼Ó©r³¶ÞµÅw¤èßf»½ö*c¾«Kk†ßóîvtÎ/š ÊU2­6ÿE‚ì ´é·xH­ï1eaèn)¼u˜‡9øàý†¸žUú0ˆGœ:ÛRÆŸ¿T¼È›øÄ¾pÁt5cpÁؾ-†ÉÓ`߸Q;6ðrlcQõØÈ™-òÃ&áÓøÈNNr0ƒÕŸ ËqÉBÕ’­'å,hùÉ>å²k¾œÄ*wù¾js˜ñgfêálÌrŽ3˜©¬:¯ùÍpæ³g±û:<ÛYÌþhv³Å¾+=Ÿ¹Í4þím ½g?—7²tu”P;d×:”Ñ‘Y­ ^E׋ÓósÔ±b›2RëxÐ5]ðMiH¯ZÒĺà”r* Ëzʺ¦`™ ËQϺ׀^ª°ï Ÿc—Ñ ¾(«'ê% ¯ÙѦõ"¬mXÜa¸Ø‡|v§7ýs[Fª°-å–¹ìîÚÜÐË=êdÃÛ’:¼ƒ²ûܳy í§ˆ,¶séí…¸ßf øµÉ×{Ã9ßÿé¨~mƒÇUø‰{5$[ÚÑN4£7._ˆÌEœy«%în”sjxJÓ·þ o“GœÒZ¥µÌsHsóXåþ Ü`SÌóZ‹<œú¸Å:tõ`£MºÀ}žºŸ ýè« 5‰ÖR§‡3èBKo‘nŽÄXký(+6ź*ö± ’K}{ôÔ¾í›­ŽŠv¶C—žq—œëŒ:Åá®ä»ûýïà|C‘Æà³§œïJ<`Ü#Æ ïÝ6<)óJy„K>Qr7‹--oGÌ;¾ò —SçëYøÒ'Pô¨ÿ¼ê™žø×“\ï,f½ä¨.bÚG>vïðæ×ÕÞ‹Oö•*¨âwßíåÁâW2ñ _S£ÿžχþÛ+k½Ê‡Ï^§&]ìá7.«Z9ïÓÏ2DB&Ü=ü#áVöf®ùþÃf¢>þþÖ«ßî@£}ÑøÏYOËöeöyå7dDAgø)Ød"TdÍG}4UC3怹õRÕE2„Öþ§R#O;†€âV`e õ?‚×ÀMˆ5+o!uõx¹ÖZÃf}%õuÑÐFZ“pºg‚2(‚R‡S+˜89õA/Èkÿ´}BbN FaW‚-k»ä„.ƒÊÇ„MˆeIèq HlØA\Ø…8†4ˆEbè]^ø…ɆhsdX†fˆ=nø†ìçilfƒJ˜>·³|Ä…{M·„bd[†‡¾4=î!,Sˆçƒ—ˆówô׈Žxˆ‰ìýÒ}û…œþ§=ŒXõS‰÷÷ˆ?h|ä,—Eo§‰©h€•x‡¦¨†—§;ä:¤†su‰ð”‰DÆ}¢¸]¿(%'”1t}®X{Xˆ`šxXcô‰[gŒVøheE„Î׋¡ÅAÆöibWóŠàèŒF÷XW%oµèF ¶gXŽA5æ§ŽêÖŽÜh„ó˜WÌ8`úlü(hˆéXE7ih‡élYu •ò¨Éþ81)… Q@h‘Úw‚™Qñ¨$ Ymi°H‘™v‹Âç4’éÁ’ûÈ’Òõ’S2“iX’7ï‘"c1ù‘*Ys5É&By^>ùbD™u¥Fy”(y`LŠlø*Ô¦TÒx“^”¾²‹ˆ"•S‰A^*ÄÈ•ëâ”ù8–a™•4Y–aé>Ýõ^`©–0…”Ìno ][9!¨F—÷pŽ<¹–UI8¥”B˜–yiCs¢yW‰ƒò|€É—G“…D‚i„ tшx¹(™I9…böYˆy™ê`\•ĘrØ™¬´™²¥YŠ£‰5¾…­iVªY¬éšØˆŽQ;haskell-98-tutorial-sources/fig2.eps0100644000106400000620000012472206774446522015772 0ustar jcpftp%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 56 633 312 705 %%Creator: CorelDRAW %%Title: %%CreationDate: Mon Mar 10 16:03:59 1997 %%DocumentProcessColors: Black %%DocumentSuppliedResources: (atend) %%EndComments %%BeginProlog /AutoFlatness true def /AutoSteps 0 def /CMYKMarks false def /UseLevel2 false def %Color profile: Disabled %%BeginResource: procset wCorel6Dict 6.0 0 % Copyright (c)1992-96 Corel Corporation % All rights reserved. v6.0 r1.1 /wCorel6Dict 300 dict def wCorel6Dict begin/bd{bind def}bind def/ld{load def} bd/xd{exch def}bd/_ null def/rp{{pop}repeat}bd/@cp/closepath ld/@gs/gsave ld /@gr/grestore ld/@np/newpath ld/Tl/translate ld/$sv 0 def/@sv{/$sv save def}bd /@rs{$sv restore}bd/spg/showpage ld/showpage{}bd currentscreen/@dsp xd/$dsp /@dsp def/$dsa xd/$dsf xd/$sdf false def/$SDF false def/$Scra 0 def/SetScr /setscreen ld/setscreen{pop pop pop}bd/@ss{2 index 0 eq{$dsf 3 1 roll 4 -1 roll pop}if exch $Scra add exch load SetScr}bd/SepMode_5 where{pop}{/SepMode_5 0 def}ifelse/CurrentInkName_5 where{pop}{/CurrentInkName_5(Composite)def}ifelse /$ink_5 where{pop}{/$ink_5 -1 def}ifelse/$c 0 def/$m 0 def/$y 0 def/$k 0 def /$t 1 def/$n _ def/$o 0 def/$fil 0 def/$C 0 def/$M 0 def/$Y 0 def/$K 0 def/$T 1 def/$N _ def/$O 0 def/$PF false def/s1c 0 def/s1m 0 def/s1y 0 def/s1k 0 def /s1t 0 def/s1n _ def/$bkg false def/SK 0 def/SM 0 def/SY 0 def/SC 0 def/$op false def matrix currentmatrix/$ctm xd/$ptm matrix def/$ttm matrix def/$stm matrix def/$fst 128 def/$pad 0 def/$rox 0 def/$roy 0 def/$fmp 50 def/$ffpnt true def/CorelDrawReencodeVect[16#0/grave 16#5/breve 16#6/dotaccent 16#8/ring 16#A/hungarumlaut 16#B/ogonek 16#C/caron 16#D/dotlessi 16#27/quotesingle 16#60/grave 16#7C/bar 16#82/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl 16#88/circumflex/perthousand/Scaron/guilsinglleft/OE 16#91/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash 16#98/tilde/trademark/scaron/guilsinglright/oe 16#9F/Ydieresis 16#A1/exclamdown/cent/sterling/currency/yen/brokenbar/section 16#a8/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/minus/registered/macron 16#b0/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered 16#b8/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown 16#c0/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla 16#c8/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis 16#d0/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply 16#d8/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls 16#e0/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla 16#e8/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis 16#f0/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide 16#f8/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def /L2?/languagelevel where{pop languagelevel 2 ge}{false}ifelse def /@BeginSysCorelDict{systemdict/Corel30Dict known{systemdict/Corel30Dict get exec}if}bd/@EndSysCorelDict{systemdict/Corel30Dict known{end}if}bd AutoFlatness {/@ifl{dup currentflat exch sub 10 gt{ ([Error: PathTooComplex; OffendingCommand: AnyPaintingOperator]\n)print flush @np exit}{currentflat 2 add setflat}ifelse}bd/@fill/fill ld/fill{currentflat{ {@fill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@eofill/eofill ld/eofill {currentflat{{@eofill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@clip /clip ld/clip{currentflat{{@clip}stopped{@ifl}{exit}ifelse}bind loop setflat} bd/@eoclip/eoclip ld/eoclip{currentflat{{@eoclip}stopped{@ifl}{exit}ifelse} bind loop setflat}bd/@stroke/stroke ld/stroke{currentflat{{@stroke}stopped {@ifl}{exit}ifelse}bind loop setflat}bd}if L2?{/@ssa{true setstrokeadjust}bd}{ /@ssa{}bd}ifelse/d/setdash ld/j/setlinejoin ld/J/setlinecap ld/M/setmiterlimit ld/w/setlinewidth ld/O{/$o xd}bd/R{/$O xd}bd/W/eoclip ld/c/curveto ld/C/c ld/l /lineto ld/L/l ld/rl/rlineto ld/m/moveto ld/n/newpath ld/N/newpath ld/P{11 rp} bd/u{}bd/U{}bd/A{pop}bd/q/@gs ld/Q/@gr ld/&{}bd/@j{@sv @np}bd/@J{@rs}bd/g{1 exch sub/$k xd/$c 0 def/$m 0 def/$y 0 def/$t 1 def/$n _ def/$fil 0 def}bd/G{1 sub neg/$K xd _ 1 0 0 0/$C xd/$M xd/$Y xd/$T xd/$N xd}bd/k{1 index type /stringtype eq{/$t xd/$n xd}{/$t 0 def/$n _ def}ifelse/$k xd/$y xd/$m xd/$c xd /$fil 0 def}bd/K{1 index type/stringtype eq{/$T xd/$N xd}{/$T 0 def/$N _ def} ifelse/$K xd/$Y xd/$M xd/$C xd}bd/x/k ld/X/K ld/sf{1 index type/stringtype eq{ /s1t xd/s1n xd}{/s1t 0 def/s1n _ def}ifelse/s1k xd/s1y xd/s1m xd/s1c xd}bd/i{ dup 0 ne{setflat}{pop}ifelse}bd/v{4 -2 roll 2 copy 6 -2 roll c}bd/V/v ld/y{2 copy c}bd/Y/y ld/@w{matrix rotate/$ptm xd matrix scale $ptm dup concatmatrix /$ptm xd 1 eq{$ptm exch dup concatmatrix/$ptm xd}if 1 w}bd/@g{1 eq dup/$sdf xd {/$scp xd/$sca xd/$scf xd}if}bd/@G{1 eq dup/$SDF xd{/$SCP xd/$SCA xd/$SCF xd} if}bd/@D{2 index 0 eq{$dsf 3 1 roll 4 -1 roll pop}if 3 copy exch $Scra add exch load SetScr/$dsp xd/$dsa xd/$dsf xd}bd/$ngx{$SDF{$SCF SepMode_5 0 eq{$SCA} {$dsa}ifelse $SCP @ss}if}bd/p{/$pm xd 7 rp/$pyf xd/$pxf xd/$pn xd/$fil 1 def} bd/@MN{2 copy le{pop}{exch pop}ifelse}bd/@MX{2 copy ge{pop}{exch pop}ifelse}bd /InRange{3 -1 roll @MN @MX}bd/wDstChck{2 1 roll dup 3 -1 roll eq{1 add}if}bd /@dot{dup mul exch dup mul add 1 exch sub}bd/@lin{exch pop abs 1 exch sub}bd /cmyk2rgb{3{dup 5 -1 roll add 1 exch sub dup 0 lt{pop 0}if exch}repeat pop}bd /rgb2cmyk{3{1 exch sub 3 1 roll}repeat 3 copy @MN @MN 3{dup 5 -1 roll sub neg exch}repeat}bd/rgb2g{2 index .299 mul 2 index .587 mul add 1 index .114 mul add 4 1 roll pop pop pop}bd/WaldoColor_5 where{pop}{/SetRgb/setrgbcolor ld/GetRgb /currentrgbcolor ld/SetGry/setgray ld/GetGry/currentgray ld/SetRgb2 systemdict /setrgbcolor get def/GetRgb2 systemdict/currentrgbcolor get def/SetHsb systemdict/sethsbcolor get def/GetHsb systemdict/currenthsbcolor get def /rgb2hsb{SetRgb2 GetHsb}bd/hsb2rgb{3 -1 roll dup floor sub 3 1 roll SetHsb GetRgb2}bd/setcmykcolor where{pop/SetCmyk_5/setcmykcolor ld}{/SetCmyk_5{ cmyk2rgb SetRgb}bd}ifelse/currentcmykcolor where{pop/GetCmyk/currentcmykcolor ld}{/GetCmyk{GetRgb rgb2cmyk}bd}ifelse/setoverprint where{pop}{/setoverprint{ /$op xd}bd}ifelse/currentoverprint where{pop}{/currentoverprint{$op}bd}ifelse /@tc_5{5 -1 roll dup 1 ge{pop}{4{dup 6 -1 roll mul exch}repeat pop}ifelse}bd /@trp{exch pop 5 1 roll @tc_5}bd/setprocesscolor_5{SepMode_5 0 eq{SetCmyk_5}{0 4 $ink_5 sub index exch pop 5 1 roll pop pop pop pop SepsColor true eq{$ink_5 3 gt{1 sub neg SetGry}{0 0 0 4 $ink_5 roll SetCmyk_5}ifelse}{1 sub neg SetGry} ifelse}ifelse}bd/findcmykcustomcolor where{pop}{/findcmykcustomcolor{5 array astore}bd}ifelse/setcustomcolor where{pop}{/setcustomcolor{exch aload pop SepMode_5 0 eq{pop @tc_5 setprocesscolor_5}{CurrentInkName_5 eq{4 index}{0} ifelse 6 1 roll 5 rp 1 sub neg SetGry}ifelse}bd}ifelse/@scc_5{dup type /booleantype eq{setoverprint}{1 eq setoverprint}ifelse dup _ eq{pop setprocesscolor_5 pop}{findcmykcustomcolor exch setcustomcolor}ifelse SepMode_5 0 eq{true}{GetGry 1 eq currentoverprint and not}ifelse}bd/colorimage where{pop /ColorImage{colorimage}def}{/ColorImage{/ncolors xd pop/dataaq xd{dataaq ncolors dup 3 eq{/$dat xd 0 1 $dat length 3 div 1 sub{dup 3 mul $dat 1 index get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div rgb2g 255 mul cvi exch pop $dat 3 1 roll put}for $dat 0 $dat length 3 idiv getinterval pop}{4 eq{/$dat xd 0 1 $dat length 4 div 1 sub{dup 4 mul $dat 1 index get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div $dat 4 index 3 add get 255 div cmyk2rgb rgb2g 255 mul cvi exch pop $dat 3 1 roll put}for $dat 0 $dat length ncolors idiv getinterval}if}ifelse}image}bd }ifelse/setcmykcolor{1 5 1 roll _ currentoverprint @scc_5/$ffpnt xd}bd /currentcmykcolor{0 0 0 0}bd/setrgbcolor{rgb2cmyk setcmykcolor}bd /currentrgbcolor{currentcmykcolor cmyk2rgb}bd/sethsbcolor{hsb2rgb setrgbcolor} bd/currenthsbcolor{currentrgbcolor rgb2hsb}bd/setgray{dup dup setrgbcolor}bd /currentgray{currentrgbcolor rgb2g}bd}ifelse/WaldoColor_5 true def/@sft{$tllx $pxf add dup $tllx gt{$pwid sub}if/$tx xd $tury $pyf sub dup $tury lt{$phei add}if/$ty xd}bd/@stb{pathbbox/$ury xd/$urx xd/$lly xd/$llx xd}bd/@ep{{cvx exec }forall}bd/@tp{@sv/$in true def 2 copy dup $lly le{/$in false def}if $phei sub $ury ge{/$in false def}if dup $urx ge{/$in false def}if $pwid add $llx le{/$in false def}if $in{@np 2 copy m $pwid 0 rl 0 $phei neg rl $pwid neg 0 rl 0 $phei rl clip @np $pn cvlit load aload pop 7 -1 roll 5 index sub 7 -1 roll 3 index sub Tl matrix currentmatrix/$ctm xd @ep pop pop pop pop}{pop pop}ifelse @rs}bd /@th{@sft 0 1 $tly 1 sub{dup $psx mul $tx add{dup $llx gt{$pwid sub}{exit} ifelse}loop exch $phei mul $ty exch sub 0 1 $tlx 1 sub{$pwid mul 3 copy 3 -1 roll add exch @tp pop}for pop pop}for}bd/@tv{@sft 0 1 $tlx 1 sub{dup $pwid mul $tx add exch $psy mul $ty exch sub{dup $ury lt{$phei add}{exit}ifelse}loop 0 1 $tly 1 sub{$phei mul 3 copy sub @tp pop}for pop pop}for}bd/@pf{@gs $ctm setmatrix $pm concat @stb eoclip Bburx Bbury $pm itransform/$tury xd/$turx xd Bbllx Bblly $pm itransform/$tlly xd/$tllx xd/$wid $turx $tllx sub def/$hei $tury $tlly sub def @gs $vectpat{1 0 0 0 0 _ $o @scc_5{eofill}if}{$t $c $m $y $k $n $o @scc_5{SepMode_5 0 eq $pfrg or{$tllx $tlly Tl $wid $hei scale <00> 8 1 false[8 0 0 1 0 0]{}imagemask}{/$bkg true def}ifelse}if}ifelse @gr $wid 0 gt $hei 0 gt and{$pn cvlit load aload pop/$pd xd 3 -1 roll sub/$phei xd exch sub /$pwid xd $wid $pwid div ceiling 1 add/$tlx xd $hei $phei div ceiling 1 add /$tly xd $psx 0 eq{@tv}{@th}ifelse}if @gr @np/$bkg false def}bd/@dlt_hsb{$fco nff ge{/$fco nff 1 sub def}if sub neg 2 div dup $fco div/kdb xd nff $fco sub div/kdb2 xd sub neg 2 div dup $fco div/kds xd nff $fco sub div/kds2 xd sub neg dup 0 eq{pop $frb 2 eq{.99}{-.99}ifelse}if dup $frb 2 eq exch 0 lt and{1 add} if dup $frb 1 eq exch 0 gt and{1 sub}if 2 div dup $fco div/kdh xd nff $fco sub div/kdh2 xd}bd/@dlt_cmyk{$fmp 50 eq{sub neg nff dup 1 gt{1 sub}if div/$dk xd sub neg nff dup 1 gt{1 sub}if div/$dy xd sub neg nff dup 1 gt{1 sub}if div/$dm xd sub neg nff dup 1 gt{1 sub}if div/$dc xd sub neg nff dup 1 gt{1 sub}if div /$dt xd}{$fco nff ge{/$fco nff 1 sub def}if sub neg 2 div dup $fco div/$dk xd nff $fco sub div/$dk2 xd sub neg 2 div dup $fco div/$dy xd nff $fco sub div /$dy2 xd sub neg 2 div dup $fco div/$dm xd nff $fco sub div/$dm2 xd sub neg 2 div dup $fco div/$dc xd nff $fco sub div/$dc2 xd sub neg 2 div dup $fco div /$dt xd nff $fco sub div/$dt2 xd}ifelse}bd/@dlt{$fse $fss sub dup/nff xd $fmp mul $fmp add 100 div round cvi dup 0 le{pop 1}if/$fco xd/$fi 0 def $frb dup 1 eq exch 2 eq or{$frt dup $frc $frm $fry $frk @tc_5 4 copy cmyk2rgb rgb2hsb 3 copy/myb xd/mys xd/myh xd $tot $toc $tom $toy $tok @tc_5 cmyk2rgb rgb2hsb 3 1 roll 4 1 roll 5 1 roll @dlt_hsb}{$frt dup $frc $frm $fry $frk @tc_5 5 copy $tot dup $toc $tom $toy $tok @tc_5 5 1 roll 6 1 roll 7 1 roll 8 1 roll 9 1 roll @dlt_cmyk}ifelse}bd/@ffnxt{/$fi $fi 1 add def $frb dup 1 eq exch 2 eq or{pop pop pop pop myh mys myb $fi $fco lt{kdb add 3 1 roll kds add 3 1 roll kdh add 3 1 roll}{kdb2 add 3 1 roll kds2 add 3 1 roll kdh2 add 3 1 roll}ifelse 3 copy /myb xd/mys xd/myh xd hsb2rgb rgb2cmyk}{$fi $fco lt $fmp 50 eq or{$dk add 5 1 roll $dy add 5 1 roll $dm add 5 1 roll $dc add 5 1 roll $dt add 5 1 roll}{$dk2 add 5 1 roll $dy2 add 5 1 roll $dm2 add 5 1 roll $dc2 add 5 1 roll $dt2 add 5 1 roll}ifelse}ifelse}bd/ffcol{5 copy $fsit 0 eq{setcmykcolor pop}{SepMode_5 0 ne {$frn findcmykcustomcolor exch setcustomcolor}{pop pop pop pop $frc $frm $fry $frk $frn findcmykcustomcolor exch setcustomcolor}ifelse}ifelse}bd/@ftl{1 index 4 index sub dup $pad mul dup/$pdw xd 2 mul sub $fst div/$wid xd 2 index sub /$hei xd pop Tl @dlt $fss 0 eq{ffcol n 0 0 m 0 $hei l $pdw $hei l $pdw 0 l @cp $ffpnt{fill}{@np}ifelse}if $fss $wid mul $pdw add 0 Tl nff{ffcol n 0 0 m 0 $hei l $wid $hei l $wid 0 l @cp $ffpnt{fill}{@np}ifelse $wid 0 Tl @ffnxt}repeat 5 rp $tot dup $toc $tom $toy $tok @tc_5 ffcol n 0 0 m 0 $hei l $pdw $hei l $pdw 0 l @cp $ffpnt{fill}{@np}ifelse 5 rp}bd/@ftrs{1 index 4 index sub dup $rox mul /$row xd 2 div 1 index 4 index sub dup $roy mul/$roh xd 2 div 2 copy dup mul exch dup mul add sqrt $row dup mul $roh dup mul add sqrt add dup/$hei xd $fst div/$wid xd 4 index add $roh add exch 5 index add $row add exch Tl $fan rotate pop pop pop pop @dlt $fss 0 eq{ffcol $fty 3 eq{$hei dup neg dup m 2 mul @sqr}{ 0 0 m 0 0 $hei 0 360 arc}ifelse $ffpnt{fill}{@np}ifelse}if 1.0 $pad 2 mul sub dup scale $hei $fss $wid mul sub/$hei xd nff{ffcol $fty 3 eq{n $hei dup neg dup m 2 mul @sqr}{n 0 0 m 0 0 $hei 0 360 arc}ifelse $ffpnt{fill}{@np}ifelse/$hei $hei $wid sub def @ffnxt}repeat 5 rp}bd/@ftc{1 index 4 index sub dup $rox mul /$row xd 2 div 1 index 4 index sub dup $roy mul/$roh xd 2 div 2 copy dup mul exch dup mul add sqrt $row dup mul $roh dup mul add sqrt add dup/$hei xd $fst div/$wid xd 4 index add $roh add exch 5 index add $row add exch Tl pop pop pop pop @dlt $fss 0 eq{ffcol $ffpnt{fill}{@np}ifelse}{n}ifelse/$dang 180 $fst 1 sub div def/$sang $dang -2 div 180 add def/$eang $dang 2 div 180 add def/$sang $sang $dang $fss mul add def/$eang $eang $dang $fss mul add def/$sang $eang $dang sub def nff{ffcol n 0 0 m 0 0 $hei $sang $fan add $eang $fan add arc $ffpnt{fill}{@np}ifelse 0 0 m 0 0 $hei $eang neg $fan add $sang neg $fan add arc $ffpnt{fill}{@np}ifelse/$sang $eang def/$eang $eang $dang add def @ffnxt} repeat 5 rp}bd/@fstAdjust{72 0 matrix defaultmatrix dtransform exch dup mul exch dup mul add sqrt currentscreen pop pop div dup mul 1 add cvi 2 256 InRange $fsc 1 sub dup 0 le{pop 1}if mul/opt$fst xd AutoSteps dup 1 eq exch 3 eq or{ opt$fst dup dup $fst dup 3 1 roll div exch 3 -1 roll gt{/$adj xd/$fst xd}{pop pop}ifelse}if AutoSteps dup 2 eq exch 3 eq or{opt$fst dup dup $fst dup 3 1 roll div exch 3 -1 roll lt{/$adj xd/$fst xd}{pop pop}ifelse}if}bd/@ff{/old$fst $fst def/$adj 1 def/$fss 0 def $o 1 eq setoverprint AutoSteps 0 gt{@fstAdjust}if 1 1 $fsc 1 sub{dup 1 sub $fsit 0 eq{$fsa exch 5 mul 5 getinterval aload pop pop /$frk xd/$fry xd/$frm xd/$frc xd/$frn _ def/$frt 1 def $fsa exch 5 mul 5 getinterval aload pop $adj mul cvi $fss add/$fse xd/$tok xd/$toy xd/$tom xd /$toc xd/$ton _ def/$tot 1 def}{$fsa exch 7 mul 7 getinterval aload pop pop /$frt xd/$frn xd/$frk xd/$fry xd/$frm xd/$frc xd $fsa exch 7 mul 7 getinterval aload pop $adj mul cvi $fss add/$fse xd/$tot xd/$ton xd/$tok xd/$toy xd/$tom xd /$toc xd}ifelse $fsit 0 eq SepMode_5 0 eq or dup not CurrentInkName_5 $frn eq and or{@sv $ctm setmatrix eoclip Bbllx Bblly Bburx Bbury $fty 2 eq{@ftc}{1 index 3 index m 2 copy l 3 index 1 index l 3 index 3 index l @cp $fty dup 1 eq exch 3 eq or{@ftrs}{pop pop pop pop $fan rotate pathbbox @ftl}ifelse}ifelse @rs /$fss $fse def}{1 0 0 0 0 _ $o @scc_5{fill}if}ifelse}for @np/$fst old$fst def} bd/@Pf{@sv SepMode_5 0 eq $Psc 0 ne or $ink_5 3 eq or{0 J 0 j[]0 d $t $c $m $y $k $n $o @scc_5 pop $ctm setmatrix 72 1000 div dup matrix scale dup concat dup Bburx exch Bbury exch itransform ceiling cvi/Bbury xd ceiling cvi/Bburx xd Bbllx exch Bblly exch itransform floor cvi/Bblly xd floor cvi/Bbllx xd $Prm aload pop $Psn load exec}{1 SetGry eofill}ifelse @rs @np}bd/F{matrix currentmatrix $sdf{$scf $sca $scp @ss}if $fil 1 eq{@pf}{$fil 2 eq{@ff}{$fil 3 eq{@Pf}{$t $c $m $y $k $n $o @scc_5{eofill}{@np}ifelse}ifelse}ifelse}ifelse $sdf{$dsf $dsa $dsp @ss}if setmatrix}bd/f{@cp F}bd/S{matrix currentmatrix $ctm setmatrix $SDF{$SCF $SCA $SCP @ss}if $T $C $M $Y $K $N $O @scc_5{matrix currentmatrix $ptm concat stroke setmatrix}{@np}ifelse $SDF{$dsf $dsa $dsp @ss}if setmatrix}bd/s{@cp S}bd/B{@gs F @gr S}bd/b{@cp B}bd/_E{5 array astore exch cvlit xd}bd/@cc{currentfile $dat readhexstring pop}bd/@sm{/$ctm $ctm currentmatrix def}bd/@E{/Bbury xd/Bburx xd/Bblly xd/Bbllx xd}bd/@c{@cp}bd/@p{ /$fil 1 def 1 eq dup/$vectpat xd{/$pfrg true def}{@gs $t $c $m $y $k $n $o @scc_5/$pfrg xd @gr}ifelse/$pm xd/$psy xd/$psx xd/$pyf xd/$pxf xd/$pn xd}bd/@P {/$fil 3 def/$Psn xd/$Psc xd array astore/$Prm xd}bd/@k{/$fil 2 def/$fmp xd /$roy xd/$rox xd/$pad xd/$fty xd/$fan xd $fty 1 eq{/$fan 0 def}if/$frb xd/$fst xd/$fsc xd/$fsa xd/$fsit 0 def}bd/@x{/$fil 2 def/$fmp xd/$roy xd/$rox xd/$pad xd/$fty xd/$fan xd $fty 1 eq{/$fan 0 def}if/$frb xd/$fst xd/$fsc xd/$fsa xd /$fsit 1 def}bd/@ii{concat 3 index 3 index m 3 index 1 index l 2 copy l 1 index 3 index l 3 index 3 index l clip pop pop pop pop}bd/tcc{@cc}def/@i{@sm @gs @ii 6 index 1 ne{/$frg true def pop pop}{1 eq{s1t s1c s1m s1y s1k s1n $O @scc_5 /$frg xd}{/$frg false def}ifelse 1 eq{@gs $ctm setmatrix F @gr}if}ifelse @np /$ury xd/$urx xd/$lly xd/$llx xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul 8 div ceiling cvi string def $bkg $frg or{$SDF{$SCF $SCA $SCP @ss}if $llx $lly Tl $urx $llx sub $ury $lly sub scale $bkg{$t $c $m $y $k $n $o @scc_5 pop}if $wid $hei abs $bts 1 eq{$bkg}{$bts}ifelse[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/tcc load $bts 1 eq{imagemask}{image}ifelse $SDF{$dsf $dsa $dsp @ss}if}{$hei abs{tcc pop}repeat}ifelse @gr $ctm setmatrix}bd/@I{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd/$llx xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div ceiling cvi string def $ngx $llx $lly Tl $urx $llx sub $ury $lly sub scale $wid $hei abs $bts[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/@cc load false $ncl ColorImage $SDF{$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd L2?{/@I_2{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd/$llx xd /$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div ceiling cvi string def $ngx $ncl 1 eq{/DeviceGray}{$ncl 3 eq{/DeviceRGB}{/DeviceCMYK} ifelse}ifelse setcolorspace $llx $lly Tl $urx $llx sub $ury $lly sub scale 8 dict begin/ImageType 1 def/Width $wid def/Height $hei abs def/BitsPerComponent $bts def/Decode $ncl 1 eq{[0 1]}{$ncl 3 eq{[0 1 0 1 0 1]}{[0 1 0 1 0 1 0 1]} ifelse}ifelse def/ImageMatrix[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]def /DataSource currentfile/ASCII85Decode filter def currentdict end image $SDF {$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd}{/@I_2{}bd}ifelse/z{exch findfont exch scalefont setfont}bd/ZB{9 dict dup begin 4 1 roll/FontType 3 def /FontMatrix xd/FontBBox xd/Encoding 256 array def 0 1 255{Encoding exch /.notdef put}for/CharStrings 256 dict def CharStrings/.notdef{}put/Metrics 256 dict def Metrics/.notdef 3 -1 roll put/BuildChar{exch dup/$char exch/Encoding get 3 index get def dup/Metrics get $char get aload pop setcachedevice begin Encoding exch get CharStrings exch get end exec}def end definefont pop}bd /ZBAddChar{findfont begin dup 4 1 roll dup 6 1 roll Encoding 3 1 roll put CharStrings 3 1 roll put Metrics 3 1 roll put end}bd/Z{findfont dup maxlength 2 add dict exch dup{1 index/FID ne{3 index 3 1 roll put}{pop pop}ifelse}forall pop dup dup/Encoding get 256 array copy dup/$fe xd/Encoding exch put dup /Fontname 3 index put 3 -1 roll dup length 0 ne{0 exch{dup type 0 type eq{exch pop}{$fe exch 2 index exch put 1 add}ifelse}forall pop}if dup 256 dict dup /$met xd/Metrics exch put dup/FontMatrix get 0 get 1000 mul 1 exch div 3 index length 256 eq{0 1 255{dup $fe exch get dup/.notdef eq{pop pop}{5 index 3 -1 roll get 2 index mul $met 3 1 roll put}ifelse}for}if pop definefont pop pop}bd /@ftx{{currentpoint 3 -1 roll(0)dup 3 -1 roll 0 exch put dup @gs true charpath $ctm setmatrix @@txt @gr @np stringwidth pop 3 -1 roll add exch m}forall}bd /@ft{matrix currentmatrix exch $sdf{$scf $sca $scp @ss}if $fil 1 eq{/@@txt/@pf ld @ftx}{$fil 2 eq{/@@txt/@ff ld @ftx}{$fil 3 eq{/@@txt/@Pf ld @ftx}{$t $c $m $y $k $n $o @scc_5{show}{pop}ifelse}ifelse}ifelse}ifelse $sdf{$dsf $dsa $dsp @ss}if setmatrix}bd/@st{matrix currentmatrix exch $SDF{$SCF $SCA $SCP @ss}if $T $C $M $Y $K $N $O @scc_5{{currentpoint 3 -1 roll(0)dup 3 -1 roll 0 exch put dup @gs true charpath $ctm setmatrix $ptm concat stroke @gr @np stringwidth pop 3 -1 roll add exch m}forall}{pop}ifelse $SDF{$dsf $dsa $dsp @ss}if setmatrix}bd /@te{@ft}bd/@tr{@st}bd/@ta{dup @gs @ft @gr @st}bd/@t@a{dup @gs @st @gr @ft}bd /@tm{@sm concat}bd/e{/t{@te}def}bd/r{/t{@tr}def}bd/o{/t{pop}def}bd/a{/t{@ta} def}bd/@a{/t{@t@a}def}bd/t{@te}def/T{@np $ctm setmatrix/$ttm matrix def}bd/ddt {t}def/@t{/$stm $stm currentmatrix def 3 1 roll m $ttm concat ddt $stm setmatrix}bd/@n{/$ttm exch matrix rotate def}bd/@s{}bd/@l{}bd/@B{@gs S @gr F} bd/@b{@cp @B}bd/@sep{CurrentInkName_5(Composite)eq{/$ink_5 -1 def}{ CurrentInkName_5(Cyan)eq{/$ink_5 0 def}{CurrentInkName_5(Magenta)eq{/$ink_5 1 def}{CurrentInkName_5(Yellow)eq{/$ink_5 2 def}{CurrentInkName_5(Black)eq {/$ink_5 3 def}{/$ink_5 4 def}ifelse}ifelse}ifelse}ifelse}ifelse}bd/@whi{@gs -72000 dup m -72000 72000 l 72000 dup l 72000 -72000 l @cp 1 SetGry fill @gr} bd/@neg{[{1 exch sub}/exec cvx currenttransfer/exec cvx]cvx settransfer @whi} bd/currentscale{1 0 dtransform matrix defaultmatrix idtransform dup mul exch dup mul add sqrt 0 1 dtransform matrix defaultmatrix idtransform dup mul exch dup mul add sqrt}bd/@unscale{}bd/@smc{CMYKMarks{0 exch eq{1 1 1 1 1 _ 0 @scc_5 pop}{1 0 0 0 0 _ 0 @scc_5 pop}ifelse}{SetGry}ifelse}bd/@gmc{CMYKMarks{GetCmyk pop pop pop 1 eq{0}{1}ifelse}{GetGry}ifelse}bd/@sqr{dup 0 rl dup 0 exch rl neg 0 rl @cp}bd/corelsym{@gs @np Tl -90 rotate 7{45 rotate -.75 2 m 1.5 @sqr fill} repeat @gr}bd/@reg_cor{@gs @np Tl -6 -6 m 12 @sqr @gs 1 @gmc sub @smc fill @gr 4{90 rotate 0 4 m 0 4 rl}repeat stroke 0 0 corelsym @gr}bd/@reg_std{@gs @np Tl .3 w 0 0 5 0 360 arc @cp @gs 1 @gmc sub @smc fill @gr 4{90 rotate 0 0 m 0 8 rl }repeat stroke @gr}bd/@reg_inv{@gs @np Tl .3 w 0 0 5 0 360 arc @cp @gs 1 @gmc sub @smc fill @gr 4{90 rotate 0 0 m 0 8 rl}repeat stroke 0 0 m 0 0 5 90 180 arc @cp 0 0 5 270 360 arc @cp fill @gr}bd/@reg_sqr{@gs @np Tl .3 w -7 -7 m 14 @sqr fill @gs 1 @gmc sub @smc 0 0 5 0 360 arc @cp save fill restore 4{90 rotate 0 0 m 0 8 rl}repeat stroke @gr 4{90 rotate 0 0 m 0 5 rl}repeat stroke @gr}bd /@reg_lng{@gs @np 0 eq{/$Xlen 16 def/$Ylen 8 def}{/$Xlen 8 def/$Ylen 16 def} ifelse Tl .3 w 0 0 5 0 360 arc @cp @gs 1 @gmc sub @smc fill @gr 90 rotate 0 0 m 0 $Xlen rl 90 rotate 0 0 m 0 $Ylen rl 90 rotate 0 0 m 0 $Xlen rl 90 rotate 0 0 m 0 $Ylen rl stroke @gr}bd/@setdcol{0 $dcol eq{0 exch 1 exch sub 0 0 0 _ 0 @scc_5 pop}{1 $dcol eq{0 exch 0 exch 1 exch sub 0 0 _ 0 @scc_5 pop}{2 $dcol eq {0 exch 0 exch 0 exch 1 exch sub 0 _ 0 @scc_5 pop}{SetGry}ifelse}ifelse}ifelse }bd/$corelmeter[1 .95 .75 .50 .25 .05 0]def/@colormeter{@gs @np 0 @setdcol 0.3 w/Courier findfont 5 scalefont setfont/yy xd/xx xd 0 1 6{dup xx 20 sub yy m 20 @sqr @gs $corelmeter exch get dup @setdcol fill @gr stroke xx 18 sub yy 2 add m exch dup 3 ge{1 SetGry}{0 @setdcol}ifelse 3 eq{pop}{100 mul 100 exch sub cvi 20 string cvs show}ifelse/yy yy 20 add def}for @gr}bd/@calbar{@gs Tl @gs @np 0 0 m @gs 20 @sqr 1 1 0 0 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 1 0 1 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 0 0 1 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 0 1 1 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 0 1 0 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 1 1 0 0 _ 0 @scc_5 pop fill @gr 20 0 Tl 0 0 m @gs 20 @sqr 1 1 1 1 0 _ 0 @scc_5 pop fill @gr @gr @np -84 0 Tl @gs 0 0 m 20 @sqr clip 1 1 0 0 0 _ 0 @scc_5 pop @gain @gr 20 0 Tl @gs 0 0 m 20 @sqr clip 1 0 1 0 0 _ 0 @scc_5 pop @gain @gr 20 0 Tl @gs 0 0 m 20 @sqr clip 1 0 0 1 0 _ 0 @scc_5 pop @gain @gr 20 0 Tl @gs 0 0 m 20 @sqr clip 1 0 0 0 1 _ 0 @scc_5 pop @gain @gr @gr}bd/@gain{10 10 Tl @np 0 0 m 0 10 360{0 0 15 4 -1 roll dup 5 add arc @cp}for fill}bd/@crop{@gs 10 div /$croplen xd .3 w 0 @smc Tl rotate 0 0 m 0 $croplen neg rl stroke @gr}bd /deflevel 0 def/@sax{/deflevel deflevel 1 add def}bd/@eax{/deflevel deflevel dup 0 gt{1 sub}if def deflevel 0 gt{/eax load}{eax}ifelse}bd/eax{{exec}forall} bd/@rax{deflevel 0 eq{@rs @sv}if}bd/@daq{dup type/arraytype eq{{}forall}if}bd /@BMP{/@cc xd 12 index 1 gt UseLevel2 true eq and{7 -2 roll pop pop @I_2}{11 index 1 eq{12 -1 roll pop @i}{7 -2 roll pop pop @I}ifelse}ifelse}bd systemdict /pdfmark known not{/pdfmark/cleartomark ld}if/@BeginEPS{$ngx 0 SetGry 0 J 0 j 1 w[]0 d 10 M false setoverprint @np/EPSDict 200 dict def EPSDict begin @sv SepMode_5 0 ne{/colorimage{@gs/sepdict 50 dict def sepdict begin[{1 exch sub} /exec cvx currenttransfer/exec cvx]cvx settransfer 3 eq/$rgb xd{$rgb{/daq0 xd /daq1 xd/daq2 xd/daq_rgb load}{/daq0 xd/daq1 xd/daq2 xd/daq3 xd/daq_cmyk load} ifelse}{/daq0 xd/daq_one load}ifelse 2 index 8 eq/8bit xd $ink_5 dup 0 lt exch 3 gt or{}{image}ifelse end @gr}bd/2cmyk{3{255 exch sub 3 1 roll}repeat 3 copy @MN @MN 3{dup 5 -1 roll sub neg exch}repeat}bd/daq_rgb{/i 0 def/daq2 load exec /daq1 load exec/daq0 load exec dup dup length 0 exch getinterval/$data xd{8bit {1 index i get 3 index i get 2cmyk 4 $ink_5 neg roll pop pop pop}{pop 0}ifelse $data i 3 -1 roll put/i i 1 add def}forall pop pop $data}bd/daq_cmyk{/daq3 load exec/daq2 load exec/daq1 load exec/daq0 load exec 4 $ink_5 neg roll pop pop pop }bd/daq_one{/$in 0 def/$out 0 def/daq0 load exec dup dup length $rgb{3}{4} ifelse idiv 0 exch getinterval/$data xd $data{pop 8bit{$rgb{0 index $in 2 add get 1 index $in 1 add get 2 index $in get 2cmyk}{0 index $in get 1 index $in 1 add get 2 index $in 2 add get 3 index $in 3 add get}ifelse 4 $ink_5 neg roll pop pop pop}{0}ifelse $data $out 3 -1 roll put/$in $in $rgb{3}{4}ifelse add def /$out $out 1 add def}forall pop $data}bd}if}bd/@EndEPS{@rs end}bd end %%EndResource %%EndProlog %%BeginSetup wCorel6Dict begin @BeginSysCorelDict 2.6131 setmiterlimit 1.00 setflat /$fst 128 def %%EndSetup %%Page: 1 1 %LogicalPage: 1 %%BeginPageSetup @sv @sm @sv %%EndPageSetup @rax %Note: Object 58.55981 672.30510 149.13468 697.42375 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 58.55981 697.42375 m 149.13468 697.42375 L 149.13468 672.30510 L 58.55981 672.30510 L 58.55981 697.42375 L @c S @rax 88.55036 680.42296 119.14384 689.30561 @E [0.00028346 0.00000000 0.00000000 0.00028346 88.55035897 680.57090424] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 42333.00000 z %CHAR: 0 0 (C) @t 24886 10625 m 28894 9611 L 28054 6318 26542 3804 24358 2076 c 22174 348 19505 -522 16349 -522 c 13085 -522 10421 144 8381 1470 c 6336 2802 4776 4728 3708 7247 c 2640 9767 2106 12485 2106 15377 c 2106 18533 2712 21286 3912 23632 c 5118 25984 6840 27772 9059 28984 c 11285 30202 13739 30814 16409 30814 c 19439 30814 21994 30040 24058 28504 c 26122 26962 27568 24784 28378 21988 C 24430 21059 L 23728 23266 22702 24874 21370 25876 c 20039 26884 18353 27388 16325 27388 c 13997 27388 12047 26830 10487 25714 c 8927 24598 7823 23092 7193 21214 c 6558 19337 6240 17393 6240 15395 c 6240 12821 6618 10571 7367 8651 c 8117 6732 9287 5286 10871 4338 c 12455 3390 14171 2910 16019 2910 c 18263 2910 20165 3558 21718 4854 c 23278 6150 24334 8075 24886 10619 c 24886 10625 L @c F %CHAR: 30576 0 (l) @t 33282 0 m 33282 30298 L 37002 30298 L 37002 0 L 33282 0 L @c F %CHAR: 39984 0 (i) @t 42798 26026 m 42792 30298 L 46512 30298 L 46512 26020 L 42798 26026 L @c 42798 0 m 42792 21946 L 46512 21946 L 46512 0 L 42798 0 L @c F %CHAR: 49392 0 (e) @t 67211 7067 m 71050 6594 L 70451 4350 69323 2598 67685 1362 c 66047 126 63947 -498 61397 -498 c 58187 -498 55638 492 53760 2466 c 51882 4446 50940 7223 50940 10787 c 50940 14477 51894 17345 53790 19385 c 55692 21424 58163 22444 61193 22444 c 64127 22444 66527 21442 68387 19451 c 70247 17453 71176 14639 71176 11015 c 71176 10799 71164 10463 71152 10019 C 54786 10019 L 54918 7613 55602 5766 56825 4488 c 58049 3204 59585 2562 61421 2562 c 62783 2562 63953 2922 64913 3636 c 65873 4350 66641 5496 67205 7067 C 67211 7067 L @c 54996 13085 m 67247 13079 L 67085 14927 66611 16313 65843 17237 c 64661 18665 63119 19385 61235 19385 c 59525 19385 58085 18809 56921 17669 c 55758 16529 55110 14993 54990 13079 C 54996 13085 L @c F %CHAR: 72936 0 (n) @t 75726 0 m 75726 21946 L 79074 21946 L 79074 18827 L 80681 21238 83015 22444 86057 22444 c 87377 22444 88601 22204 89705 21730 c 90815 21256 91649 20633 92195 19865 c 92747 19097 93137 18173 93353 17111 c 93491 16427 93563 15215 93563 13493 c 93563 0 L 89843 0 L 89843 13349 l 89843 14861 89699 16001 89411 16751 c 89123 17501 88601 18107 87869 18551 c 87131 18995 86261 19223 85271 19223 c 83687 19223 82319 18719 81173 17717 c 80021 16709 79446 14795 79446 11987 c 79446 0 L 75726 0 L @c F %CHAR: 96480 0 (t) @t 107393 3330 m 107927 36 L 106883 -180 105941 -294 105119 -294 c 103769 -294 102720 -78 101976 348 c 101232 774 100704 1338 100404 2034 c 100104 2730 99948 4194 99948 6426 c 99948 19055 L 97224 19055 L 97224 21946 L 99948 21946 L 99948 27388 L 103649 29620 L 103649 21946 L 107393 21946 L 107393 19055 L 103649 19055 L 103649 6222 l 103649 5160 103715 4476 103841 4176 c 103973 3876 104189 3630 104483 3450 c 104783 3270 105209 3180 105755 3180 c 106169 3180 106721 3228 107393 3324 C 107393 3330 L @c F T @rax %Note: Object 220.29846 672.30510 310.87332 697.42375 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 220.29846 697.42375 m 310.87332 697.42375 L 310.87332 672.30510 L 220.29846 672.30510 L 220.29846 697.42375 L @c S @rax 247.83137 680.42296 283.34013 689.30561 @E [0.00028346 0.00000000 0.00000000 0.00028346 247.83136101 680.57090424] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 42333.00000 z %CHAR: 0 0 (S) @t 1902 9737 m 5682 10061 L 5862 8549 6282 7301 6930 6336 c 7583 5364 8603 4578 9977 3978 c 11357 3378 12911 3078 14633 3078 c 16157 3078 17513 3306 18683 3756 c 19853 4212 20729 4836 21298 5628 c 21868 6420 22156 7289 22156 8225 c 22156 9173 21880 10001 21328 10709 c 20777 11417 19865 12023 18599 12503 c 17789 12815 15989 13313 13205 13979 c 10421 14645 8471 15281 7355 15875 c 5910 16631 4830 17573 4122 18695 c 3414 19817 3054 21077 3054 22468 c 3054 23992 3492 25426 4356 26752 c 5226 28084 6498 29098 8159 29782 c 9827 30466 11681 30814 13721 30814 c 15965 30814 17951 30454 19667 29734 c 21382 29014 22702 27946 23620 26542 c 24544 25138 25042 23536 25114 21760 C 21268 21472 L 21065 23386 20357 24838 19169 25810 c 17981 26788 16217 27280 13889 27280 c 11465 27280 9689 26836 8585 25948 c 7481 25060 6924 23986 6924 22732 c 6924 21646 7319 20747 8099 20045 c 8867 19349 10889 18623 14147 17891 c 17405 17153 19643 16505 20855 15953 c 22618 15143 23920 14111 24760 12863 c 25600 11615 26020 10175 26020 8555 c 26020 6948 25558 5424 24634 4002 c 23710 2574 22384 1464 20657 672 c 18929 -120 16979 -522 14819 -522 c 12077 -522 9773 -120 7925 678 c 6072 1476 4614 2682 3564 4284 c 2508 5892 1950 7709 1896 9731 C 1902 9737 L @c F %CHAR: 28236 0 (e) @t 46055 7067 m 49894 6594 L 49295 4350 48167 2598 46529 1362 c 44891 126 42791 -498 40241 -498 c 37031 -498 34482 492 32604 2466 c 30726 4446 29784 7223 29784 10787 c 29784 14477 30738 17345 32634 19385 c 34536 21424 37007 22444 40037 22444 c 42971 22444 45371 21442 47231 19451 c 49091 17453 50020 14639 50020 11015 c 50020 10799 50008 10463 49996 10019 C 33630 10019 L 33762 7613 34446 5766 35669 4488 c 36893 3204 38429 2562 40265 2562 c 41627 2562 42797 2922 43757 3636 c 44717 4350 45485 5496 46049 7067 C 46055 7067 L @c 33840 13085 m 46091 13079 L 45929 14927 45455 16313 44687 17237 c 43505 18665 41963 19385 40079 19385 c 38369 19385 36929 18809 35765 17669 c 34602 16529 33954 14993 33834 13079 C 33840 13085 L @c F %CHAR: 51780 0 (r) @t 54528 0 m 54528 21946 L 57876 21946 L 57876 18623 L 58728 20177 59519 21208 60239 21700 c 60959 22192 61763 22444 62627 22444 c 63881 22444 65159 22042 66455 21244 C 65171 17795 L 64265 18329 63353 18599 62441 18599 c 61631 18599 60899 18353 60251 17867 c 59603 17381 59141 16697 58865 15833 c 58458 14513 58248 13061 58248 11489 c 58248 0 L 54528 0 L @c F %CHAR: 65880 0 (v) @t 74765 0 m 66414 21946 L 70344 21946 L 75053 8801 l 75563 7385 76037 5904 76463 4380 C 76787 5532 77255 6930 77843 8555 c 82721 21946 L 86549 21946 L 78239 0 L 74765 0 L @c F %CHAR: 87048 0 (e) @t 104867 7067 m 108706 6594 L 108107 4350 106979 2598 105341 1362 c 103703 126 101603 -498 99053 -498 c 95843 -498 93294 492 91416 2466 c 89538 4446 88596 7223 88596 10787 c 88596 14477 89550 17345 91446 19385 c 93348 21424 95819 22444 98849 22444 c 101783 22444 104183 21442 106043 19451 c 107903 17453 108832 14639 108832 11015 c 108832 10799 108820 10463 108808 10019 C 92442 10019 L 92574 7613 93258 5766 94481 4488 c 95705 3204 97241 2562 99077 2562 c 100439 2562 101609 2922 102569 3636 c 103529 4350 104297 5496 104861 7067 C 104867 7067 L @c 92652 13085 m 104903 13079 L 104741 14927 104267 16313 103499 17237 c 102317 18665 100775 19385 98891 19385 c 97181 19385 95741 18809 94577 17669 c 93414 16529 92766 14993 92646 13079 C 92652 13085 L @c F %CHAR: 110592 0 (r) @t 113340 0 m 113340 21946 L 116688 21946 L 116688 18623 L 117540 20177 118331 21208 119051 21700 c 119771 22192 120575 22444 121439 22444 c 122693 22444 123971 22042 125267 21244 C 123983 17795 L 123077 18329 122165 18599 121253 18599 c 120443 18599 119711 18353 119063 17867 c 118415 17381 117953 16697 117677 15833 c 117270 14513 117060 13061 117060 11489 c 117060 0 L 113340 0 L @c F T @rax %Note: Object 149.79118 690.81307 219.36331 690.81420 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 149.79118 690.81364 m 207.66671 690.81364 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01600 2.01600 0 @w 219.36331 690.81364 m 207.02126 696.98268 L 207.02126 684.64063 L 219.36331 690.81364 L f @J @rax %Note: Object 151.07556 679.57569 220.01953 679.57682 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 220.01953 679.57625 m 162.77216 679.57625 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01600 2.01600 0 @w 151.07556 679.57625 m 163.41761 673.40721 L 163.41761 685.74926 L 151.07556 679.57625 L f @J @rax 168.82498 695.69887 191.70539 704.44687 @E [0.00028346 0.00000000 0.00000000 0.00028346 168.82497020 698.08476187] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 42333.00000 z %CHAR: 0 0 (r) @t 2748 0 m 2748 21946 L 6096 21946 L 6096 18623 L 6948 20177 7739 21208 8459 21700 c 9179 22192 9983 22444 10847 22444 c 12101 22444 13379 22042 14675 21244 C 13391 17795 L 12485 18329 11573 18599 10661 18599 c 9851 18599 9119 18353 8471 17867 c 7823 17381 7361 16697 7085 15833 c 6678 14513 6468 13061 6468 11489 c 6468 0 L 2748 0 L @c F %CHAR: 14100 0 (e) @t 31919 7067 m 35758 6594 L 35159 4350 34031 2598 32393 1362 c 30755 126 28655 -498 26105 -498 c 22895 -498 20346 492 18468 2466 c 16590 4446 15648 7223 15648 10787 c 15648 14477 16602 17345 18498 19385 c 20400 21424 22871 22444 25901 22444 c 28835 22444 31235 21442 33095 19451 c 34955 17453 35884 14639 35884 11015 c 35884 10799 35872 10463 35860 10019 C 19494 10019 L 19626 7613 20310 5766 21533 4488 c 22757 3204 24293 2562 26129 2562 c 27491 2562 28661 2922 29621 3636 c 30581 4350 31349 5496 31913 7067 C 31919 7067 L @c 19704 13085 m 31955 13079 L 31793 14927 31319 16313 30551 17237 c 29369 18665 27827 19385 25943 19385 c 24233 19385 22793 18809 21629 17669 c 20466 16529 19818 14993 19698 13079 C 19704 13085 L @c F %CHAR: 37644 0 (q) @t 54431 -8417 m 54425 2334 L 53849 1524 53033 846 51995 312 c 50957 -228 49847 -498 48677 -498 c 46073 -498 43830 546 41952 2622 c 40074 4698 39132 7553 39132 11177 c 39132 13385 39516 15365 40278 17111 c 41040 18863 42150 20189 43602 21089 c 45053 21988 46655 22444 48389 22444 c 51101 22444 53243 21298 54797 19013 C 54797 21946 L 58145 21946 L 58145 -8417 L 54431 -8417 L @c 42954 11039 m 42954 8213 43548 6090 44729 4680 c 45917 3270 47339 2562 48989 2562 c 50573 2562 51941 3234 53081 4578 c 54221 5922 54797 7967 54797 10703 c 54797 13625 54191 15827 52991 17297 c 51785 18773 50363 19511 48743 19511 c 47135 19511 45761 18821 44640 17453 c 43518 16085 42954 13937 42954 11033 C 42954 11039 L @c F %CHAR: 61188 0 (s) @t 62490 6552 m 66168 7127 L 66372 5652 66954 4518 67896 3738 c 68837 2958 70157 2562 71849 2562 c 73559 2562 74831 2910 75653 3606 c 76481 4302 76895 5118 76895 6054 c 76895 6894 76529 7559 75797 8039 c 75293 8363 74021 8789 71993 9299 c 69269 9983 67374 10583 66324 11087 c 65268 11591 64464 12287 63924 13175 c 63384 14063 63108 15047 63108 16121 c 63108 17093 63336 18005 63780 18833 c 64224 19667 64842 20363 65610 20915 c 66186 21340 66978 21706 67974 22000 c 68969 22294 70049 22444 71189 22444 c 72911 22444 74429 22192 75725 21700 c 77027 21208 77993 20531 78611 19685 c 79229 18839 79661 17699 79895 16283 C 76253 15791 L 76091 16919 75611 17801 74819 18431 c 74027 19067 72905 19385 71459 19385 c 69755 19385 68531 19103 67800 18539 c 67068 17975 66702 17309 66702 16553 c 66702 16073 66858 15635 67158 15251 c 67458 14855 67938 14519 68585 14261 c 68957 14123 70055 13799 71873 13307 c 74501 12611 76343 12029 77381 11585 c 78419 11141 79241 10481 79829 9629 c 80417 8777 80717 7709 80717 6444 c 80717 5208 80357 4038 79637 2946 c 78917 1854 77867 1002 76505 402 c 75137 -198 73589 -498 71873 -498 c 69023 -498 66846 96 65352 1278 c 63858 2460 62898 4224 62490 6552 C @c F T @rax 170.13770 664.63087 198.84841 673.37887 @E [0.00028346 0.00000000 0.00000000 0.00028346 170.13769456 667.01676300] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 42333.00000 z %CHAR: 0 0 (r) @t 2748 0 m 2748 21946 L 6096 21946 L 6096 18623 L 6948 20177 7739 21208 8459 21700 c 9179 22192 9983 22444 10847 22444 c 12101 22444 13379 22042 14675 21244 C 13391 17795 L 12485 18329 11573 18599 10661 18599 c 9851 18599 9119 18353 8471 17867 c 7823 17381 7361 16697 7085 15833 c 6678 14513 6468 13061 6468 11489 c 6468 0 L 2748 0 L @c F %CHAR: 14100 0 (e) @t 31919 7067 m 35758 6594 L 35159 4350 34031 2598 32393 1362 c 30755 126 28655 -498 26105 -498 c 22895 -498 20346 492 18468 2466 c 16590 4446 15648 7223 15648 10787 c 15648 14477 16602 17345 18498 19385 c 20400 21424 22871 22444 25901 22444 c 28835 22444 31235 21442 33095 19451 c 34955 17453 35884 14639 35884 11015 c 35884 10799 35872 10463 35860 10019 C 19494 10019 L 19626 7613 20310 5766 21533 4488 c 22757 3204 24293 2562 26129 2562 c 27491 2562 28661 2922 29621 3636 c 30581 4350 31349 5496 31913 7067 C 31919 7067 L @c 19704 13085 m 31955 13079 L 31793 14927 31319 16313 30551 17237 c 29369 18665 27827 19385 25943 19385 c 24233 19385 22793 18809 21629 17669 c 20466 16529 19818 14993 19698 13079 C 19704 13085 L @c F %CHAR: 37644 0 (s) @t 38946 6552 m 42624 7127 L 42828 5652 43410 4518 44352 3738 c 45293 2958 46613 2562 48305 2562 c 50015 2562 51287 2910 52109 3606 c 52937 4302 53351 5118 53351 6054 c 53351 6894 52985 7559 52253 8039 c 51749 8363 50477 8789 48449 9299 c 45725 9983 43830 10583 42780 11087 c 41724 11591 40920 12287 40380 13175 c 39840 14063 39564 15047 39564 16121 c 39564 17093 39792 18005 40236 18833 c 40680 19667 41298 20363 42066 20915 c 42642 21340 43434 21706 44430 22000 c 45425 22294 46505 22444 47645 22444 c 49367 22444 50885 22192 52181 21700 c 53483 21208 54449 20531 55067 19685 c 55685 18839 56117 17699 56351 16283 C 52709 15791 L 52547 16919 52067 17801 51275 18431 c 50483 19067 49361 19385 47915 19385 c 46211 19385 44987 19103 44256 18539 c 43524 17975 43158 17309 43158 16553 c 43158 16073 43314 15635 43614 15251 c 43914 14855 44394 14519 45041 14261 c 45413 14123 46511 13799 48329 13307 c 50957 12611 52799 12029 53837 11585 c 54875 11141 55697 10481 56285 9629 c 56873 8777 57173 7709 57173 6444 c 57173 5208 56813 4038 56093 2946 c 55373 1854 54323 1002 52961 402 c 51593 -198 50045 -498 48329 -498 c 45479 -498 43302 96 41808 1278 c 40314 2460 39354 4224 38946 6552 C @c F %CHAR: 58812 0 (p) @t 61602 -8417 m 61602 21946 L 64992 21946 L 64992 19097 L 65784 20213 66689 21053 67697 21604 c 68705 22162 69929 22444 71357 22444 c 73229 22444 74885 21958 76313 20999 c 77747 20039 78833 18671 79559 16919 c 80290 15161 80656 13229 80656 11141 c 80656 8897 80254 6870 79451 5076 c 78647 3276 77471 1896 75935 942 c 74399 -18 72779 -498 71087 -498 c 69851 -498 68735 -234 67751 288 c 66767 810 65951 1476 65322 2268 C 65322 -8417 L 61602 -8417 L @c 64974 10853 m 64974 8027 65544 5934 66683 4590 c 67823 3240 69215 2562 70841 2562 c 72491 2562 73907 3264 75083 4656 c 76259 6054 76853 8225 76853 11159 c 76853 13955 76277 16049 75131 17441 c 73979 18833 72599 19529 71003 19529 c 69419 19529 68015 18785 66797 17309 c 65580 15833 64968 13673 64968 10847 C 64974 10853 L @c F %CHAR: 81756 0 (s) @t 83058 6552 m 86736 7127 L 86940 5652 87522 4518 88464 3738 c 89405 2958 90725 2562 92417 2562 c 94127 2562 95399 2910 96221 3606 c 97049 4302 97463 5118 97463 6054 c 97463 6894 97097 7559 96365 8039 c 95861 8363 94589 8789 92561 9299 c 89837 9983 87942 10583 86892 11087 c 85836 11591 85032 12287 84492 13175 c 83952 14063 83676 15047 83676 16121 c 83676 17093 83904 18005 84348 18833 c 84792 19667 85410 20363 86178 20915 c 86754 21340 87546 21706 88542 22000 c 89537 22294 90617 22444 91757 22444 c 93479 22444 94997 22192 96293 21700 c 97595 21208 98561 20531 99179 19685 c 99797 18839 100229 17699 100463 16283 C 96821 15791 L 96659 16919 96179 17801 95387 18431 c 94595 19067 93473 19385 92027 19385 c 90323 19385 89099 19103 88368 18539 c 87636 17975 87270 17309 87270 16553 c 87270 16073 87426 15635 87726 15251 c 88026 14855 88506 14519 89153 14261 c 89525 14123 90623 13799 92441 13307 c 95069 12611 96911 12029 97949 11585 c 98987 11141 99809 10481 100397 9629 c 100985 8777 101285 7709 101285 6444 c 101285 5208 100925 4038 100205 2946 c 99485 1854 98435 1002 97073 402 c 95705 -198 94157 -498 92441 -498 c 89591 -498 87414 96 85920 1278 c 84426 2460 83466 4224 83058 6552 C @c F T @rax 97.28419 634.54365 112.53657 643.21540 @E [0.00028346 0.00000000 0.00000000 0.00028346 97.28418542 634.62696891] @tm 0 O 0 @g 0.00 0.00 0.00 1.00 k e % FontChange:/_Arial 42333.00000 z %CHAR: 0 0 (i) @t 2814 26026 m 2808 30298 L 6528 30298 L 6528 26020 L 2814 26026 L @c 2814 0 m 2808 21946 L 6528 21946 L 6528 0 L 2814 0 L @c F %CHAR: 9408 0 (n) @t 12198 0 m 12198 21946 L 15546 21946 L 15546 18827 L 17153 21238 19487 22444 22529 22444 c 23849 22444 25073 22204 26177 21730 c 27287 21256 28121 20633 28667 19865 c 29219 19097 29609 18173 29825 17111 c 29963 16427 30035 15215 30035 13493 c 30035 0 L 26315 0 L 26315 13349 l 26315 14861 26171 16001 25883 16751 c 25595 17501 25073 18107 24341 18551 c 23603 18995 22733 19223 21743 19223 c 20159 19223 18791 18719 17645 17717 c 16493 16709 15918 14795 15918 11987 c 15918 0 L 12198 0 L @c F %CHAR: 32952 0 (i) @t 35766 26026 m 35760 30298 L 39480 30298 L 39480 26020 L 35766 26026 L @c 35766 0 m 35760 21946 L 39480 21946 L 39480 0 L 35766 0 L @c F %CHAR: 42360 0 (t) @t 53273 3330 m 53807 36 L 52763 -180 51821 -294 50999 -294 c 49649 -294 48600 -78 47856 348 c 47112 774 46584 1338 46284 2034 c 45984 2730 45828 4194 45828 6426 c 45828 19055 L 43104 19055 L 43104 21946 L 45828 21946 L 45828 27388 L 49529 29620 L 49529 21946 L 53273 21946 L 53273 19055 L 49529 19055 L 49529 6222 l 49529 5160 49595 4476 49721 4176 c 49853 3876 50069 3630 50363 3450 c 50663 3270 51089 3180 51635 3180 c 52049 3180 52601 3228 53273 3324 C 53273 3330 L @c F T @rax %Note: Object 103.19046 647.84750 103.19159 672.30510 @E 0 J 0 j [] 0 d 0 R 0 @G 0.00 0.00 0.00 1.00 K 0 2.01600 2.01600 0.00000 @w 103.19102 647.84750 m 103.19102 660.60850 L S @j 0.00 0.00 0.00 1.00 K 0.00 0.00 0.00 1.00 k 0 @g 0 @G [] 0 d 0 J 0 j 0 R 0 O 0 2.01600 2.01600 0 @w 103.19102 672.30510 m 97.02198 659.96306 L 109.36403 659.96306 L 103.19102 672.30510 L f @J %%PageTrailer @rs @rs %%Trailer @EndSysCorelDict end %%DocumentSuppliedResources: procset wCorel6Dict %%EOF haskell-98-tutorial-sources/fig2.gif0100644000106400000620000000171706774446522015746 0ustar jcpftpGIF87a^a€ÿÿÿ!ù,^aÿŒ©Ëí£œ´pÎ;iÜ}E–扦êʶî«hHèò5ÃúÎ÷þ ÖlC\Î(L*—̦ó4!¥éóŠÍj·¨¨è†4„>ܲùŒvFÔ…5 Ëç’õ1ŒÓ÷üþ¼­wwcçWèò…˜¨¸ÈØèø) ÖCi#3vÉ3Ùéù *:JZj ùôtÊÚêú ++’z¨ê6›«»ËÛ;ZÛB áK\|kÈ$Œìñõ ¼|õ ­F6‰ÈVmM½¹$ ÝhÙí½ª]®¾ü8sŽ.¤þîo)æ.ÿCŸ¯cì/ÎϹ€0þLDȾ„,:ÄÇðň)»7¢Š‰þýžU’"2v׎Iä¸å¡"&ë„Ìè`;˜ÁŠLSÙÐM JßDÖSÄ'ÈÛ„Vt¶ceF¡ø,„0Í-ϸD…ÒÕ–ŸD†Æ=A/¹Þ9Ó̙ךlˆŒÅChŒ@³9|LjPžyk¯ÁéËîÆM€âžÍ pݶS†èLµoZ4‚›vëÖ°Û̉§²e¬IØã²j'ßTü5p5ÍEw†|ÔîNU£{\äͲ…7w‰.µy¸‡n¼a6Î’ô8 EQu ý÷áÞúœSMvsí×Ìdžö¼Ñ&f+Ågs_bš:‡é~ç–ôκS|V} ÎI¾Æ:d,ÿ^Ü_~–æŸ?žÞüeR / #àƒË½ÇHnJ8lâ‚•#&¸aP†¨|댸áp!&6͸bwÆØ(j¡"‰7JÈ‘iñÁHcAî¦ØŽXä˜bƒJvRÁ1[)%#î ™á’V^‰%“ ±–]ÚáG\–bŽI¦<áuÜfÈuTf–qÉ!æÙ·ævÚ'^¤§ÍcyÞ)™ É)\: ¨‹Jš‡":dT‹b—Tã )†ÌQDa}®—a¦‘nšéŒ¢òˆ›¨¦žz ‰w®Ê*€ÆJk¢³ÖŠ+¨äÊ«¦»ö 쀒K,§Ã‹l@§Z&Ë,AT6 ­žFKmÏV‹­µÓfËm×v ®·Û†K._@–‹.7°¦Ë®Bã¶ oïÆK/‘çÖ‹¯-÷æËïeëö p“óL0‹Ìæ¿/*Ã? qÄOLqÅ_ŒqÆCZ^_¬ðÇõ†,r´ydpÉýZJÖ^*ìh/ó«žX$ÏŒlÍœáLs̈ñœ¯Î2¯Ð?M¯Ñ–ÞŒô;haskell-98-tutorial-sources/title.gif0100744000106400000620000000670006774446522016236 0ustar jcpftpGIF87a…Š÷fÿÌÌÿÿÿÿ!ù,…ŠÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£ÿ)]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]«´á¿pãÊK·®Ý»xóêÝË·¯ß¿€ L¸°áÈ+^̸±ãÇ#ÿs¹²å˘3kÞ̹³çÏ C‹žÌð­èÓ¨S«^ͺµë×°%SŽM»¶íÛ¸sëÞ­šôBÓ¼ƒ N¼¸ñã¡}+޼¹óçУK×­Bp*ù#aóRøÀ¾o„üXõü‡Bø‰®…1Táïj‡ÃNMƒÅ¢ œ,&ÚPqñƒáw¸Bú-Q„º î˜Ä(ZÑ{Fd!öxÈÄ.JQ‰\œ!ߪط¬„q‹hL£ðΘ¼'zˆC‚œÆ¬xÄž½l„Z\#µ§6é%>þrf¤„æ1_ùHY"’¶¼e1wyIþi2¢Ü¦™MVnòœÜ¼aãv= 6òdº¼æ•äè+ªÓ˜´ :ÇYÍ.М׌ç9KÙÍãÑœdë'A÷9¼ƒBŸê $7øÎôéÓ•‹Rf£˜É%Ÿ­% á8#¨Ð‹~”¡ÓÔ&<[çÍV2œŠ)% j¶,>4 ©ÿ)RŠŠT Ç`¢çXru»Ü-dÏh@0Îr¼²d§x›šÛó¢w¬Êf/ÃèÇ ²¨œtma[ÏaöÑ£=,ïsÿÇȮմì$,7ÿéÓêïŠ4¬_€ykÚ®v•{íý«$ܘrØ·¬£t?EÝ)Y÷nž°‡“*aS¼•gO/)¶Îxγœî¬ç>ûÉú"ÿLèB—5Fâ“—V¡ÍhÃWrn´¤'=¦G‹Ò˜ÎôÃ,iM{úÓXâ4GAMêR«LÔƒ6µªW0T—‹Õ°ŽµíÉTËúÖ¸Öš«Ç—ë^ûše»Vô¯‡k>ûؘÿ66²±Êl…-µl ì²ál|Mþ…£âh4cjûØÊ¾¶qÇíl<ØÛ!wµŸ=ì³ÛJl/YÅ-¨uÓûÅ@žÓn£|oÚ»ßn6›Š–Rr|\ÿ>8`CÛ]œÞÏ¢4Õ*“Ù|+á´^¦­/n\.¿“}m·å÷cyâuÀ?eÂSÎðÞ¹Á6ì¹c6‚|Þ,ÞÊsþ[÷¾÷ç`­ïi…rïŽY¦/ç9Æ}ÖW+¸;Ö0‘‡Ú ¶€ îñ·Õñn<çWïøÍ¥ýÒÑÂ8ËÕ1Ù9n…O}¯éhssËÞ¯FS¸O_zmí¼x¹çþ,oÄe|ó k}ai>zÊÛ~ð·Õã_3"ëže,ÛüÝíÞ¹ßopr/ó“ç·ety¿ë¼ëÓµÒAoø–—¹ì+­zç#ZzÓ3¾ñòË:ÅQûØ@ÖvᵬYº}{ÜÛ/eûcg¡nX“û½m¾¯®‹põUþ¾hv£z±òÙr_ù¦6êI¬úÕËýð‘ÿr„}|~Ê£_ð|:õ«¿ö¤CžÈ#½Ý1œô¼Ï¿ß%çe®7q›ÕNîeÙ&}\Çt¯åtá÷€é¢y8Äòx¢b¸™¢øâ 8‚‡"‚$x‚~b‚(¸‚u¢‚,ø‚'08ƒˆâ‚4xƒùÅ€ûå€8؃bƒ>„s#ƒBX„C„F˜„Ë5~JV~Jø„‡¶wMÇkPX…ÑÅ„qæ„V¸…P„\ø…ƒ„`8†‰%†dx†”b†h¸†•†…¦…l‡›æ†—&‡v8‡:(hA|؇~ø‡€ˆ‚8ˆ„XˆRQmÞ‘ˆŠ¸ˆŒØˆµÑ!©çˆ’8‰”X‰–ØH~—¸‰œØ‰žx‰™Ø„Ÿ8ФXЦØ¡˜…§¸Š¬ØŠ®Ø|÷в8‹´X‹…‘Šoh‹º¸‹¼Ø‹ë↌Â8ŒÄXŒÆxŒÈØH±ŒÌØŒÎøŒÐ5Ò8ÔXÖxØ˜Ú¸ÜØÞøàŽâ8ŽäXŽæxŽè˜Žê¸ŽìØŽîøŽðò¸Ž;haskell-98-tutorial-sources/html.config0100644000106400000620000000202706774446522016556 0ustar jcpftpaux=haskell-tutorial.aux aux=haskell.aux htmldir=html/ refs=tutrefs morerefs=reportrefs files= intro.verb files= goodies.verb files= functions.verb files= patterns.verb files= classes.verb files= moretypes.verb files= io.verb files= stdclasses.verb files= monads.verb files= numbers.verb files= modules.verb files= pitfalls.verb files= arrays.verb files= end.verb files= haskell-tutorial.bbl index=html/indextutorial.html ~style= ~top=top ~id=A Gentle Introduction to Haskell, Version 98
~footer=
~idback next ~top ~sfooter=
~idnext ~top ~efooter=
~idback ~top ~header=~style ~idback next ~top
~sheader=~style ~idnext ~top
~eheader=~style ~idback ~top
~indexHeader=Haskell 98 Index
~style

Gentle Intro: Index


haskell-98-tutorial-sources/tex.hs0100644000106400000620000016354207121452775015563 0ustar jcpftp{- This is the pre-processor which converts the Latex / verbatim of the Haskell Report into HTML. This program has evolved in a rather unplanned manner and is now a jumble of absolutely crappy code, tacked-on features, no documentation, and other fun stuff. I dislike the other tex -> html translations so I wrote my own. So there. At least you can tweak the heck out of this thing to make the html look just right if you want to. Lots of stuff could be made more automatic. There's still a bunch of stuff I do by hand to latex code. Especially the images in figures. The parsing code here is absolutely terrible. I wrote it before the parser library was part of Hugs. Also everything is way too stateful. I will cheerfully refund your money if you don't like this software. This code runs under Hugs 1.4. Probably under all the other Haskell compilers too. To run, just change to the directory containing the .tex / .hs / .verb files and run main. It always reads `html.config' to setup parameters. Configuration file stuff: aux = file Add definitions in a latex .aux file htmldir = directory Output directory files = file1, file2, ... Files to be processed. Cumulative. index = file Index file to be generated if given. All section headings are hyperlinked from the index. refs = file file resolving refs to files. Maps latex tags onto the html file where they are defined. morerefs = file For refs to another document for hyperlinks across docs style = s1, s2, ... Set document style(s). Styles: report -- latex document style article -- latex document style microsoftsymbols -- Use microsoft symbol font ~mac = value Define macros used in raw html #comment Only on separate lines. You can probably make the generated stuff a lot prettier by changing the html in the page header / footer. Within the latex file, here's what's special: %** raw html ~foo expands the definition of foo. ~prev and ~next are special %*anchor on/off Add labels to Haskell source code %*ignore Define lines to be ignored. %*endignore %*section n Set current section number. Gotta do this for appendix. Some special latex commands (you need to add the definitions to the latex file). \newcommand{\anchor}[2]{#2} -- \anchor{url}{text in anchor} \newcommand{\inputHS}{\input} \input{foo} include the Haskell source file foo.hs \newcommand{\outlinec}{\outline} % Centered outlines in html No expansion of Tex definitions is attempted. You gotta add every user-defined latex command to the master table. Many primitive latex commands are supported but not all. John Peterson -} module Main where import Monad(foldM) import IO hiding (bracket) import Char(isSpace, isAlpha, isDigit) import IOExts(unsafePerformIO) -- debugging only data FontStyle = RM | IT | TT | Bold | Sym | UL deriving (Eq,Show) data Font = Font FontStyle Int String -- Has a size and color deriving (Eq, Show) ttFont = Font TT 3 "" mathFont = Font IT 3 "" romanFont = Font RM 3 "" instance Show (a -> b) where showsPrec _ _ = showString "" data HaskellDef = HVars [String] | HTycon String | HInstance String String deriving Show data HTML = HProtect [HTML] -- Boundary for local font changes | HString String -- data characters in text mode | HISO String -- ISO character name | HPara -- Paragraph break | HCmd String -- a raw html command | HEol -- a soft end of line | HVerb String -- A string of chars in Verb mode | HVerbLine String -- as above with a newline | HAnchor String HTML -- Hyperlinked text | HDef String -- hyperlink label definition | HSub HTML -- Subscript | HSuper HTML -- Superscript | HQuote HTML -- Quoted text | HCenter HTML -- Centered text | HFont FontStyle -- Font selection. | HColor String -- Color selection. | HSize Int -- Size selection. | HLineBreak -- Hard line break (
) | HTable String String [Int] HTML -- Tables. | HSep -- Column separation in a table | HHdr Int String HTML -- Heading with anchor | HList String HTML -- Itemized lists and friends | HItem HTML -- List bullet | HSpecial Int -- Special character | HEmpty deriving Show type PC = IO (State, String, [String]) type PCFun = State -> String -> [String] -> PC emit :: HTML -> PCFun emit h s = doChar (h +++ s) h +++ s = s {html = h : html s} h +++. s = s {html = h : dropWhite (html s)} dropWhite (HEol : h) = dropWhite h dropWhite (HPara : h) = dropWhite h dropWhite h = h delimiter :: String -> PCFun delimiter d s l ls = do -- putStr ("Closing: " ++ d ++ "\n") (head (delims s)) d s l ls catchd :: (String -> [HTML] -> PCFun) -> State -> String -> [String] -> PCFun -> PC catchd f s l ls k = do -- putStr ("open at " ++ l ++ "\n") k s' l ls where s' = s {delims = (passHtml f (html s)) : delims s, html = []} passHtml f h = \d s -> f d (reverse (html s)) (s {html = h, delims = tail (delims s)} ) reqDelim :: String -> ([HTML] -> HTML) -> PCFun -> (String -> [HTML] -> PCFun) reqDelim d f k = \d' h s l ls -> if d == d' then k (f h +++ s) l ls else do putStr ("Missing " ++ d ++ ", found " ++ d' ++ " instead.\n") doChar s l ls reqDelim1 :: String -> ([HTML] -> HTML) -> PCFun -> (String -> [HTML] -> PCFun) reqDelim1 d f k = \d' h s l ls -> if d == d' then k (f h +++ s) l ls else do putStr ("Missing " ++ d ++ ", found " ++ d' ++ " instead.\n") return (s,l,ls) getArg :: (HTML -> PCFun) -> PCFun getArg k s l ls = getArgf1 '{' '}' k s l ls getArg2 :: (HTML -> HTML -> PCFun) -> PCFun getArg2 f = getArg (\h1 -> getArg (\h2 -> f h1 h2)) getArg3 :: (HTML -> HTML -> HTML -> PCFun) -> PCFun getArg3 f = getArg (\h1 -> getArg (\h2 -> getArg (\h3 -> f h1 h2 h3))) getArgf1 :: Char -> Char -> (HTML -> PCFun) -> PCFun getArgf1 open close k s l ls = getArgf2 (trim l) ls where getArgf2 "" [] = do putStr "EOF where arg expected\n" delimiter "EOF" s "" [] getArgf2 "" (l:ls) = getArgf2 (trim l) ls getArgf2 l@(c:cs) ls | c == open = catchd (reqDelim [close] HProtect (retArg k)) s cs ls doChar | otherwise = k HEmpty s l ls retArg :: (HTML -> PCFun) -> PCFun retArg k s l ls = k (head (html s)) (s {html = tail (html s)}) l ls -- This program reads in a configuration file as a argument. If no -- argument is given, the default is "config.html" main = do configFile <- getConfig s <- parseConfig configFile s' <- processFiles s writeRefFile s' writeIndexFile s' getConfig :: IO String getConfig = return "html.config" writeRefFile s = case (refFile s) of "" -> return () f -> do putStr ("Writing reference file " ++ f ++ "\n") catch (writeFile f (concat (map fmtKV (newRefMap s)))) (\e -> do putStr ("Can't write ref file: " ++ f ++ "\n") return ()) where fmtKV (k,v) = k ++ "=" ++ v ++ "\n" writeIndexFile s = case (indexFile s) of "" -> return () f -> do putStr ("Writing index file " ++ f ++ "\n") let cmd = case (lookup "indexHeader" (macdefs s)) of Just _ -> macroExpand s "~indexHeader" ++ "\n" _ -> "" hdrs = concat (map (\h -> [HItem HEmpty, h, HEol]) (reverse (indexHTML s))) idx = htmlToString (HProtect [HCmd cmd, HList "item" (HProtect hdrs)]) catch (writeFile f idx) (\e -> do putStr ("Can't write index file: " ++ f ++ "\n") return ()) -- parseConfig parses a configuration file to yield an initial state -- An entry in the config file is a 'tag = value' pair. Tags supported are: -- aux = file Add definitions in a latex .aux file -- proganchors = file Anchor the listed productions. One per file line. -- syntaxanchors = file Anchor the listed functions. One per file line. -- htmldir = directory Output directory -- files = file1, file2, ... Files to be processed. Cumulative. -- index = file index file to be generated if given -- refs = file file resolving refs to files. -- style = style Set document style -- ~mac = value Macro definition -- #comment Only on separate lines. parseConfig :: String -> IO IState parseConfig f = catch (do c <- readFile f foldM configLine initState (lines c)) (\e -> error ("Can't read configuration file " ++ f)) configLine s l | "#" `starts` l = return s | l == "" = return s | otherwise = let (k,v) = parseKV l in case k of "aux" -> do putStr ("Reading aux file " ++ v ++ "\n") a <- readAuxFile v return (s {auxInfo = auxInfo s ++ a}) "proganchors" -> do a <- readAnchorFile v return (s {panchors = panchors s ++ a}) "files" -> return (s {sourceFiles = sourceFiles s ++ parseCommas v}) "htmldir" -> return (s {htmlDir = v}) "index" -> return (s {indexFile = v}) "refs" -> do refs <- readRefFile v return (s {refFile = v, refMap = refs}) -- Has to come after refs "morerefs" -> do morerefs <- readRefFile v return (s {refMap = refMap s ++ morerefs}) "style" -> return (s {style = parseCommas v}) '~':m -> return (s {macdefs = (m,v) : macdefs s}) _ -> badline where badline = error ("Bad line in config:\n" ++ l ++ "\n") readRefFile :: String -> IO [(String, String)] readRefFile f = catch (do l <- readFile f return (map parseKV (lines l))) (\e -> do putStr ("Can't read ref file: " ++ f ++ "\n") return []) readAuxFile :: String -> IO [(String,String)] readAuxFile f = catch (do l <- readFile f return (processAuxLines (lines l))) (\e -> do putStr ("Can't read aux file: " ++ f ++ "\n") return []) readAnchorFile :: String -> IO [String] readAnchorFile f = catch (do l <- readFile f return (lines l)) (\e -> do putStr ("Can't read anchor file: " ++ f ++ "\n") return []) -- Look for \newlabel{label}{value} in aux files. Ignore all else. processAuxLines :: [String] -> [(String,String)] processAuxLines [] = [] processAuxLines (l:ls) | "\\newlabel" `starts` l = f 10 3 "" | "\\bibcite" `starts` l = f 9 2 "$" | otherwise = rest where rest = processAuxLines ls f x1 x2 prefix = (prefix++name,val) : rest where dropNewLabel = drop x1 l -- kills \newlabel{ or \bibcite{ (name,r) = break (== '}') dropNewLabel r' = drop x2 r val = takeWhile (/= '}') r' parseKV l = let (k,l1) = span (/= '=') l val = case l1 of ('=':v) -> trim v _ -> "" in (trimr k,val) parseCommas :: String -> [String] parseCommas "" = [] parseCommas l = let (tok,l') = break (== ',') l in filter (/= ' ') tok : (case l' of "" -> [] (_:l'') -> parseCommas l'') -- Data Defintions -- Current mode in Latex source data IState = IState { sourceFiles :: [String], auxInfo :: [(String,String)], panchors :: [String], sanchors :: [String], anchorMode :: Bool, htmlDir :: String, sourceFile :: String, indexFile :: String, indexHTML :: [HTML], verbMode :: Bool, section :: [String], avoidSectionBump :: Bool, inMath :: Bool, inQuotes :: Bool, refFile :: String, refMap :: [(String,String)], newRefMap :: [(String,String)], style :: [String], macdefs :: [(String,String)]} deriving Show initState = IState { sourceFiles = [], auxInfo = [], panchors = [], sanchors = [], anchorMode = False, htmlDir = "", sourceFile = "", indexFile = "", indexHTML = [], verbMode = False, section = [], avoidSectionBump = False, inQuotes = False, inMath = False, refFile = "", refMap = [], newRefMap = [], style = ["article"], macdefs=[]} -- This is the `changable' part of the state. Save updates by pushing -- global stuff into the `gs' field. data State = State {html :: [HTML], delims :: [String -> PCFun], gs :: IState} deriving Show -- This is the initial state at the start of the file initLS :: IState -> State initLS s = State {gs = s, delims = [], html = []} -- These control the formatting of syntax processFiles :: IState -> IO IState processFiles s = do --putStr (show s ++ "\n") doFile (sourceFiles s) s "" where doFile [] s _ = return s doFile (file:fs) s p = do s' <- processFile (addp s p fs) file doFile fs s' file addp s p fs = s {macdefs = ("prev",fname p) : ("next",case fs of (f:_) -> fname f; _ -> "") : macdefs s} fname f = let (file,_) = parseFileName f in file processFile :: IState -> String -> IO IState processFile s f = let (file,ext) = parseFileName f s' = s {sourceFile = file, verbMode = ext == ".verb"} outFile = htmlDir s ++ file ++ ".html" in do catch (do putStr ("Reading " ++ f ++ "\n") l <- readFile f (html,s'') <- texToHtml s' (lines l) putStr ("Writing " ++ outFile ++ "\n") catch (do writeFile outFile (htmlToString html) return s'') (\e -> do putStr ("Write to " ++ outFile ++ " failed.\n") return s')) (\e -> do putStr ("File " ++ outFile ++ " error " ++ (show e) ++ "\n") return s') parseFileName f = let (re,rf) = span (/= '.') (reverse f) in case (re,rf) of (_,'.':f') -> (reverse f','.':(reverse re)) _ -> (f,"") -- This sets up the parts of the state that need to be reset at the start of -- each file. texToHtml :: IState -> [String] -> IO (HTML, IState) texToHtml s ls = do (s',_,_) <- catchd (reqDelim1 "EOF" HProtect (\s l ls -> return (s,l,ls))) (initLS s) "" ls doChar -- print (html s') return (HProtect (html s'),gs s') -- This is the main loop for scanning each line of the input file. scanLines :: State -> [String] -> PC scanLines s [] = delimiter "EOF" s "" [] scanLines s (l:ls) | htmlLine l = handleCommand s l ls -- | l == "@" && verbMode (gs s) = doCodeLines s ls | l == "@@@" && verbMode (gs s) = doSyntaxLines s ls | texComment l = scanLines s ls | l == "" = scanLines (HPara +++. s) (dropWhile (== "") ls) | otherwise = doChar s l ls where -- Lines starting %* are commands to this preprocessor. htmlLine l = case l of ('%':'*':_) -> True _ -> False texComment l = case l of ('%':_) -> True _ -> False -- This handles commands to this preprocessor endcoded as %* lines in the -- source. handleCommand s l ls | "*" `starts` c = scanLines (HCmd (macroExpand (gs s) (tail c) ++ "\n") +++ s) ls | l == "%*ignore" = case dropWhile (/= "%*endignore") ls of [] -> error "Missing %*endignore" (l:ls) -> scanLines s ls | otherwise = do s' <- docmd htmlCommands scanLines s' ls where c = drop 2 l (cmd,args') = span isAlpha c args = trim args' docmd :: [(String,State -> String -> IO State)] -> IO State docmd [] = do putStr ("Bad preprocessor cmd: " ++ cmd ++ "\n") putStr ("Args: " ++ args ++ "\n") return s docmd ((c,fn):cs) | c == cmd = fn s args | otherwise = docmd cs -- Worlds stupidest macro expansion macroExpand s str = exp1 str where exp1 "" = "" exp1 ('~':str) = let (n,r) = span isAlpha str d = lookup n (macdefs s) in case d of Just v -> exp1 (v++r) Nothing -> "Missing var " ++ n ++ "\n" ++ exp1 r exp1 (c:str) = c : exp1 str -- These are handlers for the special commands to this preprocessor (%*). htmlCommands :: [(String, State -> String -> IO State)] htmlCommands = [("anchor",doAddAnchors), ("section",doSetSection), ("dump", doDump)] -- These are the handlers for the commands. They return a new state and -- some html -- %*anchor on adds designated anchors to syntax and source code -- %*anchor off doAddAnchors :: State -> String -> IO State doAddAnchors s a = return (s {gs = (gs s) {anchorMode = a == "on"}}) -- %*section n sets current section to n (can't set subsections) -- care is needed to avoid bumping the section -- on the next \section. doSetSection :: State -> String -> IO State doSetSection s a = return (s {gs = (gs s) {section = s1, avoidSectionBump = not (null s1)}}) where s1 = if null a then [] else [a] -- For debugging doDump :: State -> String -> IO State doDump s a = do putStr ("Syntax anchors: \n" ++ concat (map (++ " ") (sanchors (gs s)))) putStr ("Code Anchors:\n" ++ concat (map (++ " ") (panchors (gs s)))) putStr ("Refs:\n" ++ concat (map (\a -> show a ++ " ") (refMap (gs s)))) return s -- This handles lines in verbatim mode as initiated by a single @ on a line. -- Don't mix line-by-line verbatim and within a line verbatim! -- This is where Haskell definitions are anchored doCodeLines s (l:ls) | l == "@" = scanLines s ls | otherwise = do s' <- emitCodeLine s l doCodeLines s ls emitCodeLine s l | anchorMode (gs s) = case maybeAnchor l of Nothing -> return (HVerbLine l +++ s) Just anc -> let labs = entityToLabels anc a = HProtect (map HDef labs ++ [HVerbLine l]) in do s' <- registerAnchors labs s return (a +++ s') | otherwise = return (HVerbLine l +++ s) emitCodeLines s [] = return s emitCodeLines s (l:ls) = do s' <- emitCodeLine s l emitCodeLines s' ls maybeAnchor :: String -> Maybe HaskellDef maybeAnchor l | "data " `starts` l = Just (HTycon (dataName (drop 5 l))) | "newtype " `starts` l = Just (HTycon (dataName (drop 8 l))) | "type " `starts` l = Just (HTycon (dataName (drop 5 l))) | "class " `starts` l = Just (HTycon (dataName (drop 6 l))) | "instance " `starts` l = Just (anchorInstance (drop 9 l)) | not (null l) && (not (isSpace (head l))) = maybeAnchorSignature l | otherwise = Nothing dropContext l = trim (dc1 l l) where dc1 ('=' : '>' : l') l = l' dc1 [] l = l dc1 (_:l1) l = dc1 l1 l dataName s = getTok (trim (dropContext s)) -- Totally Bogus! anchorInstance s = let s' = trim (dropContext s) (c,s'') = break isSpace s' s1 = trim s'' t = case (getTok s1) of "(IO" -> "IO" "(a->b)" -> "a->b" "[]" -> "[a]" x -> x in HInstance c t maybeAnchorSignature s = case parseCL s of ([],_) -> Nothing (names,r) -> case (trim r) of (':' : ':' : c : _) -> if isSpace c then Just (HVars names) else Nothing _ -> Nothing _ -> Nothing parseCL ('(':s) = parseOp s parseCL s@(c:_) | isAlpha c = let (var,s') = span (\c -> isAlpha c || c == '_' || isDigit c || c == '\'') s (v,r) = parseCL1 (trim s') in (var:v,r) | otherwise = ([],"") parseOp s = let (op,s') = break (== ')') s in case s' of (')':s) -> let (v,r) = parseCL1 s in (op:v,r) _ -> ([],"") parseCL1 (',':s) = parseCL (trim s) parseCL1 s = ([],s) -- This handles lines of syntax definition syntaxCols :: [Int] syntaxCols = [100,20,250] doSyntaxLines :: State -> [String] -> PC doSyntaxLines s ls = do (hs, gs', ls') <- doSyntaxLine (initLS (gs s)) ls let h' = HTable "cellspacing=0 cellspacing=0" "" syntaxCols (HProtect hs) scanLines (s {gs = gs' {inMath = inMath (gs s)}, html = h' : html s}) ls' doSyntaxLine s [] = error "Eof in syntax mode!" doSyntaxLine s (l:ls) | l == "@@@" = return (html s, gs s, ls) | emptyLine l = doSyntaxLine (HLineBreak +++ s) (dropWhile emptyLine ls) | definitionLine l = defLine s l ls | otherwise = continuedLine s l ls emptyLine "" = True emptyLine ('%':_) = True emptyLine _ = False definitionLine l = case (trim l) of ('|':cs) -> False _ -> True -- This handles lines defining Haskell syntax (@@@). These lines either -- start with a non-terminal or a |. This determines which: continuedLine s l ls = do (hs,gs) <- texToHtml ((gs s) {inMath = True}) ["& @|@ &" ++ l'] let h' = unProtect hs ++ [HLineBreak] doSyntaxLine (s {gs = gs, html = html s ++ h'}) ls where l' = tail (trim l) -- trim the leading | defLine s l ls = do (hs,gs) <- texToHtml ((gs s) {inMath = True}) [tok ++ tok' ++ " & " ++ arrow ++ l'] let gs' = if doAnchor then removeSyntaxAnchor tok gs else gs h' = a ++ unProtect hs ++ [HLineBreak] doSyntaxLine (s {gs = gs', html = html s ++ h'}) ls where doAnchor = anchorMode (gs s) && tok `elem` sanchors (gs s) (tok,rest) = span isAN l (tok',r') = break isSpace rest (_,r'') = span isSpace r' (l',hasArrow) = case r'' of ('-':'>':cs) -> (cs, True) cs -> (cs, False) arrow | hasArrow = " {\\tt \\rightarrow} &" | otherwise = "" a = if doAnchor then [HAnchor ("syntax-" ++ tok) HEmpty] else [] removeSyntaxAnchor tok gs = gs -- Needs to be fixed! unProtect (HProtect x) = unProtect' x unProtect x = [x] unProtect' [HProtect x] = unProtect' x unProtect' x = x -- This is the main character dispatcher doChar :: PCFun doChar s "" ls = scanLines (HEol +++ s) ls -- end of line doChar s (c:cs) ls = case c of '@' | verbMode (gs s) -> case cs of ('@':cs') -> put "@" cs' _ -> do (s',l',ls') <- doVerb s cs ls doChar s' l' ls' '%' -> scanLines s ls -- Tex comment '\\' -> doTexCommand s cs ls '$' -> doChar (setMath s (not mathMode)) cs ls '"' | verbMode (gs s) -> if inQuotes (gs s) then delimiter "\"" (s {gs = (gs s) {inQuotes = False}}) cs ls else catchd (reqDelim "\"" (\h -> HProtect (HFont IT:h)) (\s -> doChar (setMath s mathMode))) (s {gs = (gs s) {inMath = True, inQuotes = True}}) cs ls doChar '~' -> put " " cs '_' -> if mathMode then subsuper HSub else put "_" cs '^' -> if mathMode then subsuper HSuper else put "^" cs '\'' -> case cs of ('\'':cs') -> put "\"" cs' _ -> put "'" cs '`' -> case cs of ('`':cs') -> put "\"" cs' _ -> put "`" cs '{' -> catchd (reqDelim "}" HProtect doChar) s cs ls doChar '&' -> emit HSep s cs ls '}' -> delimiter "}" s cs ls _ -> let (l',l'') = break (`elem` "@%\\$\"~_^'`{&}") cs in put (c:l') l'' where mathMode = inMath (gs s) put str r = emit (HString str) s r ls put' h r = emit h s r ls subsuper fn = getArg (doSuper fn) s (addBraces cs) ls doSuper fn h s l ls = emit (fn h) s l ls addBraces "" = "" addBraces (s@('{':cs)) = s addBraces (c:cs) = '{':c:'}':cs -- Won't catch x^\foo popMath s = doChar (setMath s False) setMath s b = s {gs = (gs s) {inMath = b}} doTexCommand s l ls = let (cmd,args) = parseTexCommand l doISO = emit (HISO (drop 3 cmd)) s args ls badCmd = do putStr ("Tex command " ++ cmd ++ " not recognized\n") doChar s args ls in if "ISO" `starts` cmd then doISO else case lookup cmd texCommands of Just hndlr -> hndlr s (trim args) ls Nothing -> badCmd parseTexCommand "" = ("","") parseTexCommand cs | isAlpha (head cs) = let (t,a) = span (\c -> isAlpha c || isDigit c || c == '*') cs in (t, a) | otherwise = ([head cs],tail cs) -- This handles verbatim mode. This should not be handling code mode -- which starts with a single @ on a line. doVerb s "" [] = error "End of file in verb mode" doVerb s "" (l:ls) = doVerb (HVerb "\n" +++ s) l ls doVerb s ('@':'@':l) ls = doVerb (HVerb "@" +++ s) l ls doVerb s ('@':l) ls = return (s, l, ls) -- Exit verb mode doVerb s l ls = doVerb (HVerb l' +++ s) l'' ls where (l',l'') = span (/= '@') l --- Indexing stuff maybeIndex :: State -> String -> HTML -> IO (String, State) maybeIndex s sect title = let tag = "sect" ++ sect in case (indexFile (gs s)) of "" -> return (tag,s) _ -> let h = HAnchor (sourceFile (gs s) ++ ".html#" ++ tag) title in return (tag, s {gs = (gs s) {indexHTML = h : indexHTML (gs s)}}) {- inTable s = case tableStuff s of Nothing -> False _ -> True -- let Just (a,i,m) = tableStuff s s' = setTableStuff (Just (a,i+1,m)) s in ("") ++. doChar s' cs ls | inTable s && c == '\\' && "\\" `starts` cs = let Just (a,_,m) = tableStuff s s' = setTableStuff (Just (a,0,m)) s in ("") ++. doChar s' (skipBracket (tail cs)) ls | mathMode s = doMChar case c of '$' -> exitMath -} -- This strips off latex command args. Not robust at all! Should do a -- deeper parse. Missing arguments are ignored. ignore1 :: Char -> Char -> Int -> String -> [String] -> (String,[String]) ignore1 opn cls k l ls = ignore2 k l ls 0 where ignore2 0 l ls lev = (l,ls) ignore2 k "" [] lev = ("",[]) ignore2 k "" (l:ls) lev = ignore2 k l ls lev ignore2 k (c:cs) l lev | c == opn = ignore2 k cs l (lev+1) | c == cls && lev == 0 = (cs,l) -- Error! | c == cls && lev == 1 = ignore2 (k-1) cs l 0 | c == cls = ignore2 k cs l (lev-1) | isSpace c = ignore2 k cs l lev | lev == 0 = (c:cs,l) | otherwise = ignore2 k cs l lev -- This is a really poor parser for simple string args to commands. -- Assume (for now) that no line breaks are in the argument getSArg :: String -> [String] -> (String,String,[String]) getSArg l ls = getSArg2 '{' '}' l ls getBArg :: String -> [String] -> (String,String,[String]) getBArg l ls = getSArg2 '[' ']' l ls getSArg2 open close s ls = (s1, s2, ls) where (s1,s2) = case trim s of (c:cs) -> if c == open then b cs 0 else ("",c:cs) str -> ("",str) b "" i = ("","") b (c:cs) i | c == open = cons1 open (b cs (i+1)) b (c:cs) 0 | c == close = ("",cs) b (c:cs) i | c == close = cons1 close (b cs (i-1)) b (c:cs) i = cons1 c (b cs i) cons1 c (cs,x) = (c:cs,x) starts [] _ = True starts _ [] = False starts (a:as) (b:bs) | a == b = starts as bs | otherwise = False alternate :: [a] -> a -> [a] alternate [] _ = [] alternate [l] _ = [l] alternate (l:ls) a = l : a : alternate ls a trim s = dropWhile isSpace s trimr s = reverse (dropWhile isSpace (reverse s)) getTok s = takeWhile (\c -> not (isSpace c)) s isReport s = "report" `elem` style (gs s) isArticle s = "article" `elem` style (gs s) useMSSymbols s = "microsoftsymbols" `elem` style (gs s) sectStyle s | isReport s = 1 | isArticle s = 0 | otherwise = error "Bad style" (.|.) :: PCFun -> PCFun -> PCFun f1 .|. f2 = \s -> if useMSSymbols s then f1 s else f2 s --- Handlers for Tex commands texCommands :: [(String,PCFun)] texCommands = [("\\",doEol), ("newline",doEol), ("",ignore 0), ("-",ignore 0), ("markboth",ignore 2), ("begin",doBegin), ("end",doEnd), ("item",doItem), ("bibitem",doBibItem), ("Large",emit (HSize 4)), ("bf",emit (HFont Bold)), ("tt",emit (HFont TT)), ("vspace",ignore 1), ("em",emit (HFont IT)), ("cite",doCite), ("noindent",ignore 0), ("Haskell",use "Haskell "), ("chapter",doSection 1), -- only in report ("chapter*",embed (HHdr 1 "")), -- only in report ("section",\s -> doSection (1+sectStyle s) s), ("section*",\s -> embed (HHdr (2+sectStyle s) "") s), ("subsection",\s -> doSection (2+sectStyle s) s), ("subsection*",\s -> embed (HHdr (3+sectStyle s) "") s), ("subsubsection",\s -> doSection (3+sectStyle s) s), ("subsubsection*",\s -> embed (HHdr (3+sectStyle s) "") s), ("paragraph",embed (HHdr 3 "")), ("paragraph*",embed (HHdr 3 "")), ("label",doLabel), ("ref",doRef), ("sref",\s -> doRef (HString "Section " +++ s)), -- mpj ("bi",doBeginItemize), ("ei",delimiter "itemize"), ("bto",doBeginTabularB), -- has a border ("eto",delimiter "tabular"), (">",emit HSep), ("=",emit HSep), ("kill",ignore 0), ("underline",embed (\h -> HProtect [HFont IT, h])), ("`",ignore 0), ("'",ignore 0), ("#",use "#"), ("%",use "%"), ("frac", doFrac), ("ignorehtml",ignore 1), ("bprog",emit (HVerb "\n")), ("bprogNoSkip",ignore 0), ("eprog", emit (HVerb "\n")), ("eprogNoSkip",ignore 0), ("footnote",bracket " (" ")"), ("bkqA",use "`"), ("bkqB",use "`"), ("bkq",use "`"), ("protect",ignore 0), ("qquad",emit (HVerb " ")), ("mbox",ignore 0), ("anchor",doAnchor), ("outline",embed boxed), ("outlinec",embed (HCenter . boxed)), ("ecaption",embed (\a -> (HCenter (HHdr 3 "" a)))), ("nopagebreak",ignoreB), ("rm",embed (inFont RM)), ("it",emit (HFont IT)), ("em",emit (HFont IT)), ("bf",emit (HFont Bold)), ("input",doInput), ("[",doEqn), ("]",delimiter "\\]"), (" ",use " "), ("verb",doVerbc), ("ba",doBa "ea"), ("bt",doBa "et"), ("ea",delimiter "ea"), ("et",delimiter "et"), ("rangle",use ">"), ("langle",use "<"), ("tr",embed (inFont RM)), ("{",use "{"), ("}",use "}"), ("index",ignore 1), ("indexclass",ignore 1), ("indexdi",ignore 1), ("indexsyn",ignore 1), ("indextt",ignore 1), ("indexmodule",ignore 1), ("indextycon",ignore 1), ("indexsynonym",ignore 1), ("arity",expandS (\a -> "{\\rm arity(}" ++ a ++ "{\\rm )}")), ("infix",expandS (\a -> "{\\rm infix(}" ++ a ++ "{\\rm )}")), ("nopagebreak",ignoreB), ("struthack",ignore 1), ("hline",ignore 0), ("centerline",ignore 0), ("hspace*",ignore 1), ("pageref",ignore 1), ("/",ignore 0), (",",use " "), ("kappa",emitSym "k"), ("overline",embed (\h -> HProtect [HFont UL, h])), ("multicolumn",ignore 2), ("pi",emitSym "p"), ("epsilon",emitSym "e"), ("prime",use "'"), ("clearpage",ignore 0), ("medskip",ignore 0), ("syn",bracket "[" "]"), ("S",use "report section "), ("newpage",ignore 0), ("_",use "_"), ("epsbox",ignore 1), ("caption",ignore 1), ("hspace",ignore 1), ("cleardoublepage",ignore 0), ("bprogB",ignore 0), ("eprogB",ignore 0), ("startnewsection",ignore 0), ("inputHS",doInputHS), ("pagenumbering",ignore 1), ("pagestyle",ignore 1), ("setcounter",ignore 2), ("LaTeX",use "LaTeX"), ("copyright", emit (HISO "copy")), ("newblock", ignore 0), ("figcaption", doFigCaption), -- For the tutorial: ("see",doSee), -- For mpj: ("ts",ignore 0), ("la",use "<"), ("ra",use ">"), ("prei",ignore 0), ("nextitem",doItem), ("smon",ignore 0), ("smoff",ignore 0), ("metaArg",embed (\h -> HProtect [HFont RM, h])), ("inbox",embed boxed), ("clarg",getArg3 (\h1 h2 h3 -> emit ( boxed (HProtect [ inFont IT h2, HString " ", inFont RM h1])))), ("cls",ignore 2), ("cldone",ignore 0), ("helponly",ignore 1), ("htmlonly",ignore 1), ("latexonly",ignore 1), ("latexignore",ignore 1), ("helprefn",getArg2 (\h1 h2 -> emit h1)), ("parag",embed (HHdr 3 "")), ("showURL",getArg2 (\h1 h2 -> emit (HProtect [HProtect [HFont TT,h1],h2]))), ("mailto",getArg (\h -> emit (HProtect [HFont TT,h]))), -- For Haskore ("extended",ignore 0), ("basic", ignore 1), ("small", ignore 0), -- No need for small print in this version ("bot",emitSym "^" .|. use "_|_"), ("ne",emitSymc 185 .|. use "/="), ("neq",emitSymc 185 .|. use "/="), ("cdots",emitSymc 188 .|. use "..."), ("red",emitSymc 222 .|. use "=>"), ("equiv",emitSymc 186 .|. use "="), ("Rightarrow",emitSymc 222 .|. use "=>"), ("rightarrow",emitSymc 174 .|. use "->"), ("ast",emitSym "*" .|. use "*"), ("forall",emitSym "\"" .|. use "forall "), ("geq",emitSymc 179 .|. use ">="), ("leq",emitSymc 163 .|. use "<="), ("ldots",emitSymc 188 .|. use "..."), ("geq2",emit (HProtect [symFont [HSpecial 179],HString "2"]) .|. use ">=2"), ("geq0",emit (HProtect [symFont [HSpecial 179],HString "0"]) .|. use ">=0") ] use :: String -> PCFun use str = emit (HString str) symFont :: [HTML] -> HTML symFont x = HProtect (HFont Sym : x) emitSym :: String -> PCFun emitSym s = emit (symFont [HString s]) emitSymc :: Int -> PCFun emitSymc c = emit (symFont [HSpecial c]) ignore k s l ls= let (l',ls') = ignore1 '{' '}' k l ls in doChar s l' ls' ignoreB s l ls = let (l',ls') = ignore1 '[' ']' 1 l ls in doChar s l' ls' bracket s1 s2 = getArg (\h -> emit (HProtect [HString s1, h, HString s2])) embed :: (HTML -> HTML) -> PCFun embed hf = getArg (\h -> emit (hf h)) withArg :: (HTML -> State -> IO (HTML, State)) -> PCFun withArg f = getArg (\h s l ls -> do (h',s') <- f h s emit h' s' l ls) withBArg :: (String -> State -> IO (HTML, State)) -> PCFun withBArg f s l ls = let (arg,l',ls') = getBArg l ls in do (h,s') <- f arg s emit h s' l' ls' expandS :: (String -> String) -> PCFun expandS f s l ls = let (str,l',ls') = getSArg l ls in doChar s (f str ++ l') ls' boxed = HTable "border=2 cellpadding=3" "l" [] inFont f h = HProtect [HFont f, h] doEol s l ls = let (l',ls') = ignore1 '[' ']' 1 l ls in emit HLineBreak s l' ls' doBegin s l ls = let (a,l',ls') = getSArg l ls in if a == "tabular" || a == "table" then let (d,l'',ls'') = getSArg l' ls' in catchd (reqDelim a (doBlock a d) doChar) s l'' ls'' ignoreB else if a == "thebibliography" then -- Just ignore it let (_,l'',ls'') = getSArg l' ls' in doChar s l'' ls'' else if a == "verbatim" then doVerbatim s l' ls' "\\end{verbatim}" else if a == "code" then doVerbatim s l' ls' "\\end{code}" else catchd (reqDelim a (doBlock a "") doChar) s l' ls' ignoreB doBeginItemize s l ls = catchd (reqDelim "itemize" (doBlock "itemize" "") doChar) s l ls doChar doBeginArray s l ls = let (d,l',ls') = getSArg l ls in catchd (reqDelim "array" (doBlock "array" d) doChar) s l' ls' doChar doBeginTabular s l ls = let (d,l',ls') = getSArg l ls in catchd (reqDelim "tabular" (doBlock "tabular" d) doChar) s l' ls' doChar doBeginTabularB s l ls = let (d,l',ls') = getSArg l ls in catchd (reqDelim "tabular" (doBlock "tabular" ("border=2;" ++ d)) doChar) s l' ls' doChar doVerbatim s "" [] e = error "End of file in verbatim mode" doVerbatim s l ls@(l':ls') e | e `starts` l = doChar s (drop 14 l) ls | otherwise = doVerbatim (HVerb (l ++ "\n") +++ s) l' ls' e doBlock a d hs = let h = HProtect hs in case a of "itemize" -> HList "item" h "quote" -> HQuote h "flushright" -> HTable "" "r" [] h "center" -> HCenter h "enumerate" -> HList "enum" h "description" -> HList "description" h "figure" -> boxed h -- What to do with figures?? "figure*" -> boxed h -- What to do with figures?? "table" -> HCenter h "tabular" -> HTable opts d' [] h "tabbing" -> HTable opts d' [] h "exercise" -> HProtect [HPara, HProtect [HFont Bold, HString "Exercise", HLineBreak], h, HPara] "theorem" -> HProtect [HPara, HProtect [HFont Bold, HString "Theorem", HLineBreak], h, HPara] "axiom" -> HProtect [HPara, HProtect [HFont Bold, HString "Axiom", HLineBreak], h, HPara] _ -> HString ("Unknown begin: \\begin{" ++ a ++ "}\n") where (opts,d') = case (break (== ';') d) of (str,"") -> ("", str) (o,';':s) -> (o,s) doEnd s l ls = let (a,l',ls') = getSArg l ls in if a == "thebibliography" then doChar s l' ls' else delimiter a s l' ls' doItem = withBArg (\tag s -> do (h,_) <- texToHtml (gs s) [tag] return (HItem h,s)) doBibItem s l ls = let (_,l',ls') = getBArg l ls (tag',l'',ls'') = getSArg l' ls' tag = "$" ++ tag' ref = case lookup tag (auxInfo (gs s)) of Just n -> n _ -> tag' in do s' <- registerAnchor tag s emit (HProtect [HDef tag, HString ("[" ++ ref ++ "] ")]) s' l'' ls'' doVerbc s (delim:cs) ls = doChar (HVerb str +++ s) l' ls' where (str, l',ls') = takeDelim cs ls takeDelim "" [] = error "EOF in \\verb" takeDelim "" (l:ls) = let (s',l',ls') = takeDelim l ls in ("\n" ++ s',l',ls') takeDelim (c:cs) ls | c == delim = ("",cs,ls) | otherwise = let (s',l',ls') = takeDelim cs ls in (c:s',l',ls') doSection k = withArg (\sectName s -> do let s' = maybeBump s k sectNum = sectionNumber s' if k<3 then putStr (sectNum ++ "\n") else return () let html = HProtect [HString sectNum, HVerb " ", sectName] (anchor,s'') <- maybeIndex s' sectNum html s3 <- registerAnchor anchor s'' return (HHdr (k+1) anchor html,s3)) maybeBump s k = s {gs = mb1 (gs s)} where mb1 s | avoidSectionBump s = s {avoidSectionBump = False} | otherwise = s {section = bumpSect (section s) k} bumpSect [] i = ["1"] bumpSect (s:_) 1 = [incStr s] bumpSect (s:ss) i = s : bumpSect ss (i-1) incStr s = show (i+1) where i :: Int i = case reads s of [(j,_)] -> j _ -> 0 doLabel s l ls = let (a,l',ls') = getSArg l ls in do s' <- registerAnchor a s emit (HDef a) s' l' ls' registerAnchor name s = case refFile (gs s) of "" -> return s _ -> return (s {gs = (gs s) {newRefMap = (name,sourceFile (gs s)) : newRefMap (gs s)}}) registerAnchors names s = case refFile (gs s) of "" -> return s _ -> return (s {gs = (gs s) {newRefMap = map (\name -> (name,sourceFile (gs s))) names ++ newRefMap (gs s)}}) doRef s l ls = let (a,l',ls') = getSArg l ls txt = lookup a (auxInfo (gs s)) file = lookup a (refMap (gs s)) anc x = case file of Just fn -> HAnchor (fn ++ ".html#" ++ a) x Nothing -> x in case txt of Just x -> emit (anc (HString x)) s l' ls' Nothing -> do putStr ("Ref not found: " ++ a ++ "\n") emit (HString "??") s l' ls' doCite s l ls = let (a,l',ls') = getSArg l ls args = map ("$"++) (parseCommas a) refs = refMap (gs s) aux = auxInfo (gs s) anc a x = case lookup a refs of Just fn -> HAnchor (fn ++ ".html#" ++ a) x Nothing -> x cites = alternate cites' (HString ", ") cites' = map (\a -> case lookup a aux of Just r -> anc a (HString r) _ -> HString "??") args in do sequence (map (\v -> case (lookup v aux) of Nothing -> putStr ("Cite not found: " ++ tail v ++ "\n") _ -> return ()) args) emit (HProtect ([HString "["] ++ cites ++ [HString "]"])) s l' ls' doAnchor s l ls = let (url,l',ls') = getSArg l ls in embed (\a -> (HAnchor url a)) s l' ls' doInput s l ls = let (f,l',ls') = getSArg l ls in do putStr ("Reading input " ++ f ++ "\n") newLines <- catch (do l1 <- readFile (f ++ (if verbMode (gs s) then ".verb" else ".tex")) return (lines l1)) (\err -> do putStr ("Input error: " ++ show err) return []) doChar s "" (newLines ++ [l'] ++ ls') doInputHS s l ls = let (f,l',ls') = getSArg l ls in do putStr ("Reading Haskell input " ++ f ++ ".hs\n") newLines <- catch (do l1 <- readFile (f ++ ".hs") return (lines l1)) (\err -> do putStr ("Input error: " ++ show err) return []) s' <- emitCodeLines s newLines doChar s' l' ls' doEqn s l ls = catchd (reqDelim "\\]" (\h -> HProtect ([HPara] ++ h ++ [HPara])) popMath) (setMath s True) l ls doChar -- Pretty awful rendition of frac. doFrac = getArg2 (\d n -> emit (HProtect [HString "", n, HString "/(", d, HString ") "])) doFigCaption = getArg (\c s l ls -> let (lab,l',ls') = getSArg l ls fignum = case lookup lab (auxInfo (gs s)) of Just l -> l Nothing -> "??" in emit (HCenter ( HProtect [ HFont Bold, HString ("Figure " ++ fignum ++ ": "), c])) s l' ls') -- As far as I can figure out, table elements are not in math mode -- even when the table itself is encountered while in math mode (?) doBa d s l ls = let (arg,l1,ls1) = getBArg l ls (align,l2,ls2) = getSArg l1 ls1 in catchd (reqDelim d (\h -> HTable "" align [] (HProtect h)) doChar) s l2 ls2 doChar sectionName s = b (section (gs s)) where b [] = "" b [x] = x ++ " " b (x:xs) = x ++ "." ++ b xs doSee s l ls = let (ref,l',ls') = getSArg l ls txt = lookup ref (auxInfo (gs s)) file = lookup ref (refMap (gs s)) anc x = case file of Just fn -> HAnchor ("../onlinereport/" ++ fn ++ ".html#" ++ ref) x Nothing -> x in case txt of Just x -> emit (anc (HProtect [HISO "sect" ,HString x])) s l' ls' Nothing -> do putStr ("Ref not found: " ++ ref ++ "\n") emit (HString "??") s l' ls' -- This is the HTML output phase htmlToString :: HTML -> String htmlToString h = emitRM h romanFont -- The HTML state consists of the current HTML string, the current font, -- the new font, and the newline flag. type HTMLS = (String,Font,Font,Bool) ht1 :: HTML -> String -> Font -> Font -> Bool -> HTMLS ht1 h s cf nf@(Font style sz color) nl = case h of HProtect hs -> let hs' = rotateDefs hs (s',cf',nf',nl') = emitl hs' s cf nf nl in (s',cf',nf,nl') HString str -> hemit str HISO str -> hemitV ("&" ++ isoTrans str ++ ";") HPara -> ("

\n"++s,cf,nf,True) HCmd str -> huse str HEol -> huse "\n" HVerb str -> hemitTT str False HVerbLine str -> hemitTT (str ++ "\n") True HAnchor str h -> remit ("") "" h False HDef str -> huse ("") HSub h -> remit "" "" h False HSuper h -> remit "" "" h False HCenter h -> remit "

" "
" h True HQuote h -> remit "
" "
" h True HFont f -> newFont (Font f sz color) HColor color' -> newFont (Font style sz color') HSize i -> newFont (Font style i color) HSep -> hemit " -- Bad & -- " HLineBreak -> ("
\n"++s,cf,nf,True) HHdr i s h -> remit (addAnchor s ++ "") ("") h True HTable opts align' widths (HProtect hs) -> let align = filter (`elem` "lrc") align' in case parseTable hs of [] -> (s,cf,nf,nl) (r:rs) -> (exitFont cf ++ "\n" ++ doTableRow align widths r ++ concat (map (doTableRow align []) rs) ++ "
\n" ++ s,romanFont, nf,True) HItem h -> huse "Dangling \\item" HList style (HProtect h) -> let hs = parseItems h items = concat (map singleItem hs) singleItem (HItem h:hs) = case style of "description" -> "
" ++ emitRM h nf ++ "
\n" ++ r _ -> "
  • " ++ r where r = emitRM (HProtect hs) nf singleItem _ = "" (start,end) = case style of "item" -> ("
      ","
    ") "enum" -> ("
      ","
    ") "description" -> ("
    ","
    ") in (exitFont cf ++ start ++ items ++ end ++ s, romanFont, nf, True) HEmpty -> (s,cf,nf,nl) HSpecial c -> hemitV ("&#" ++ show c ++ ";") _ -> error ("No emit for " ++ show h) where hemit str = (changeFont cf nf ++ htmlEncode str s, nf, nf, False) hemitV str = (changeFont cf nf ++ str ++ s, nf, nf, False) huse str = (str ++ s,cf,nf, False) remit s1 s2 h nl' = let (s',cf',nf',_) = ht1 h (exitFont cf' ++ s2 ++ s) romanFont nf nl in (exitFont cf ++ s1 ++ s', romanFont, nf ,nl') emitl [] s cf nf nl = (s, cf, nf, nl) emitl (h:hs) s cf nf nl = let (s1,cf1,nf1,nl1) = ht1 h sn cf nf nl (sn,cfn,nfn,nln) = emitl hs s cf1 nf1 nl1 in (s1,cfn,nfn,nln) hemitTT str forceNL = (changeFont cf ttFont ++ (if forceNL && (not nl) then "
    \n" else "") ++ htmlEncodeVerb str s, ttFont, nf, forceNL) newFont f = (s,cf,f,nl) doTableRow align widths rows = "" ++ tr1 align ws rows ++ "" where aligns = align ++ repeat 'l' ws :: [Int] ws = widths ++ repeat 0 tr1 (a:as) = tr2 a as -- default align = 'l' tr1 [] = tr2 'l' [] tr2 a as (w:ws) = tr3 a as w ws -- default width = 0 tr2 a as [] = tr3 a as 0 [] tr3 a as w ws (r:rs) = tableRow a w r ++ tr1 as ws rs tr3 _ _ 0 _ [] = [] tr3 a as w ws [] = tableRow a w [HEmpty] ++ tr1 as ws [] tableRow a w r = " "" 'c' -> " align=center" 'r' -> " align=right" _ -> error ("Bad alignment: " ++ [a] ++ "\n") ++ case w of 0 -> "" n -> " width=" ++ show n ++ ">" ++ emitRM (HProtect r) nf ++ "" addAnchor "" = "" addAnchor s = "\n" htmlEncode [] s = s htmlEncode ('>':cs) s = ">" ++ htmlEncode cs s htmlEncode ('<':cs) s = "<" ++ htmlEncode cs s htmlEncode ('&':cs) s = "&" ++ htmlEncode cs s htmlEncode (c :cs) s = c : htmlEncode cs s htmlEncodeVerb [] s = s htmlEncodeVerb ('>' :cs) s = ">" ++ htmlEncodeVerb cs s htmlEncodeVerb ('<' :cs) s = "<" ++ htmlEncodeVerb cs s htmlEncodeVerb ('&' :cs) s = "&" ++ htmlEncodeVerb cs s htmlEncodeVerb (' ' :cs) s = " " ++ htmlEncodeVerb cs s htmlEncodeVerb ('\n':cs) s = "
    \n" ++ htmlEncodeVerb cs s htmlEncodeVerb (c :cs) s = c : htmlEncodeVerb cs s parseTable :: [HTML] -> [[[HTML]]] parseTable hs = map (\r -> splitList r isHSep) (splitList hs isHLineBreak) isHSep HSep = True isHSep _ = False isHLineBreak HLineBreak = True isHLineBreak _ = False splitList :: [a] -> (a -> Bool) -> [[a]] splitList [] _ = [] splitList (l:ls) sep | sep l = [] : splitList ls sep | otherwise = acons l (splitList ls sep) parseItems :: [HTML] -> [[HTML]] parseItems [] = [] parseItems (h@(HItem _) : hs) = [] : acons h (parseItems hs) parseItems (h : hs) = acons h (parseItems hs) acons :: a -> [[a]] -> [[a]] acons x [] = [[x]] acons x (l:ls) = (x:l):ls changeFont f1 f2 = if f1 /= f2 then exitFont f1 ++ enterFont f2 else "" enterFont (Font s 3 "") = enterFontStyle s enterFont (Font s sz color) = "" ++ enterFontStyle s where fs 3 = "" fs x = "size=" ++ show x ++ " " fc "" = "" fc c = "color=" ++ c enterFontStyle RM = "" enterFontStyle IT = "" enterFontStyle Bold = "" enterFontStyle TT = "" enterFontStyle Sym = "" enterFontStyle UL = "" exitFont (Font s 3 "") = exitFontStyle s exitFont (Font s _ _) = exitFontStyle s ++ "" exitFontStyle RM = "" exitFontStyle IT = "" exitFontStyle Bold = "" exitFontStyle TT = "" exitFontStyle Sym = "" exitFontStyle UL = "" emitRM h f = let (s,cf,nf,nl) = ht1 h (exitFont cf) romanFont f True in s isAN x = isAlpha x || isDigit x -- According to the lastest W3 stuff I have these names wrong. isoTrans "brkbar" = "#166" isoTrans "hibar" = "#175" isoTrans "suptwo" = "#178" isoTrans "supthree" = "#179" isoTrans "supone" = "#185" isoTrans "fracfourth" = "#188" isoTrans "frachalf" = "#189" isoTrans "fracthreeforths" = "#190" isoTrans x = x sectionNumber s = b (section (gs s)) where b [] = "" b [s] = s b (s:s') = s ++ "." ++ b s' -- This pulls labels in front of section headers. In Tex you have -- \section{blah} \label{blah} which is the wrong order for the html. rotateDefs :: [HTML] -> [HTML] rotateDefs defs = rd1 (reverse defs) [] where rd1 [] a = a rd1 (d@(HDef _) : hs) a = let (headers,rest) = span isHeader hs in rd1 rest ([d] ++ reverse headers ++ a) rd1 (x:xs) a = rd1 xs (x:a) isHeader HPara = True isHeader HEol = True isHeader (HHdr _ _ _) = True isHeader _ = False --- These are the name manglers to map names with symbols onto alphas entityToLabels :: HaskellDef -> [String] entityToLabels (HTycon t) = ["$t" ++ mangleName t] entityToLabels (HInstance c t) = ["$i" ++ mangleName c ++ "$$" ++ mangleName t] entityToLabels (HVars vars) = map (\v -> "$v" ++ mangleName v) vars mangleName r = concat $ map (\c -> case c of '(' -> "$P" ')' -> "$C" '-' -> "$D" '>' -> "$A" '[' -> "$B" ']' -> "$c" ',' -> "$x" '#' -> "$p" '$' -> "$D" '|' -> "$b" '!' -> "$E" '&' -> "$A" '^' -> "$U" '>' -> "$G" '<' -> "$L" '=' -> "$Q" _ -> [c]) r mangleType t = mangleName (case t of "(IO" -> "IO" "(a->b)" -> "(->)" "[a]" -> "[]" x -> x) haskell-98-tutorial-sources/index.html0100644000106400000620000000460106774446522016420 0ustar jcpftpA Gentle Introduction to Haskell, Version 98
    Annoying Graphic Logo
    Paul Hudak, Yale University
    John Peterson, Yale University
    Joseph Fasel, Los Alamos National Laboratory

    September 28, 1999

    This is the HTML version of the Gentle Introduction To Haskell, version 98.

    Brief Table of Contents.

    The master version of the Haskell Tutorial is at haskell.org. Any corrections or changes in the report are found there.

    All code in this tutorial, with additional commentary, is found in the code directory packaged with this tutorial. We suggest that you inspect, run, and modify this code as you read the tutorial. This code has been tested on Hugs 98.

    Copyright (C) 1999 Paul Hudak, John Peterson and Joseph Fasel

    Permission is hereby granted, free of charge, to any person obtaining a copy of "A Gentle Introduction to Haskell" (the Text), to deal in the Text without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Text, and to permit persons to whom the Text is furnished to do so, subject to the following condition: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Text. haskell-98-tutorial-sources/make-html0100775000106400000620000000043406774446522016232 0ustar jcpftp#! /bin/bash # You need to change the runhugs path echo "Generating html for tutorial in ./html" echo "Run this twice to get references right" echo "Report must be in ../report for hyperlinks to work" rm -fr html mkdir html cp *.gif html cp *.html html cp -r code html runhugs tex.hs haskell-98-tutorial-sources/makefile0100644000106400000620000000125706774446522016127 0ustar jcpftp# Makefile for the Haskell tutorial # For whatever reason you might have explicitly make verbatim first. RM = rm -f LATEX=latex RUNHUGS=~/local/bin/runhugs98 .SUFFIXES: .verb .tex .dvi .ps .verb.tex: verbatim expand < $< | ./verbatim >$@ .tex.dvi: $(LATEX) $< .dvi.ps: dvips -o $*.ps $< haskell-tutorial.ps: haskell-tutorial.dvi haskell-tutorial.dvi: verbatim haskell-tutorial.tex intro.tex goodies.tex \ functions.tex \ patterns.tex classes.tex moretypes.tex io.tex \ stdclasses.tex monads.tex numbers.tex \ modules.tex pitfalls.tex arrays.tex end.tex verbatim: verbatim.lex lex verbatim.lex cc lex.yy.c -lfl -o verbatim rm lex.yy.c haskell-98-tutorial-sources/verbatim.lex0100644000106400000620000000517706774446522016757 0ustar jcpftp%START NORM VERB MATH SYNTAX sp [ \t]* verb \n{sp}@{sp}\n math \n{sp}\"{sp}\n synt \n{sp}@@@{sp}\n nl {sp}\n{sp} %{ #define PUSH states[top++] = #define POP BEGIN states[--top] %} %% int states[256]; int top; BEGIN NORM; top = 0; @@ { printf ("@"); } @ { printf ("\\mbox{\\tt "); PUSH NORM; BEGIN VERB; } @ { printf ("}"); POP; } {verb} { printf ("\n\\mbox{\\tt "); PUSH NORM; BEGIN VERB; } {verb} { printf ("}\n"); POP; } ^{sp}\n { printf ("}\\\\[-8pt]\n\\mbox{\\tt "); } \n { printf ("}\\\\\n\\mbox{\\tt "); } " " { printf ("\\ "); } @@ { printf ("@"); } \# { printf ("{\\char'43}"); } \$ { printf ("{\\char'44}"); } \% { printf ("{\\char'45}"); } \& { printf ("{\\char'46}"); } \~ { printf ("{\\char'176}"); } \_ { printf ("{\\char'137}"); } \^ { printf ("{\\char'136}"); } \\ { printf ("{\\char'134}"); } \{ { printf ("{\\char'173}"); } \} { printf ("{\\char'175}"); } \"\" { printf ("\""); } \"{sp} { printf ("\\mbox{$\\it "); PUSH NORM; BEGIN MATH; } {sp}\" { printf ("$}"); POP; } {math}{sp} { printf ("\n\\[\n\\it "); PUSH NORM; BEGIN MATH; } {sp}{math} { printf ("\n\\]\n"); POP; } {nl} { printf ("\\\\\n\\it "); } {sp}&{sp} { printf ("&\\it "); } \\{nl} { } {sp} { printf ("\\ "); } "..." { printf ("\\ldots "); } ">=" { printf ("\\geq "); } "<=" { printf ("\\leq "); } "->" { printf ("\\rightarrow "); } "<-" { printf ("\\leftarrow "); } @@ { printf ("@"); } @ { printf ("\\makebox{\\tt "); PUSH MATH; BEGIN VERB; } {synt}{sp} { printf ("\n\\begin{flushleft}"); printf ("\\it\\begin{tabbing}\n"); printf ("\\hspace{0.6in}\\="); printf ("\\hspace{3.1in}\\=\\kill\n$\\it "); BEGIN SYNTAX; } {sp}{synt} { printf ("$\n\\end{tabbing}\\end{flushleft}\n"); BEGIN NORM; } {nl} { printf ("$\\\\ \n$\\it "); } {sp}"->"{sp} { printf ("$\\>\\makebox[3.5em]{$\\rightarrow$}"); printf ("$\\it "); } {nl}"|"{sp} { printf ("$\\\\ \n$\\it "); printf ("$\\>\\makebox[3.5em]{$|$}$\\it "); } {sp}&{sp} { printf ("$\\>\\makebox[3em]{}$\\it "); } \\{nl} { } {sp} { printf ("\\ "); } "..." { printf ("\\ldots "); } ">=" { printf ("\\geq "); } "<=" { printf ("\\leq "); } "->" { printf ("\\rightarrow "); } "<-" { printf ("\\leftarrow "); } @@ { printf ("@"); } @ { printf ("\\makebox{\\tt "); PUSH SYNTAX; BEGIN VERB; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������haskell-98-tutorial-sources/code/�������������������������������������������������������������������0040755�0001064�0000062�00000000000�06774446522�015337� 5����������������������������������������������������������������������������������������������������ustar �jcp�����������������������������ftp��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������haskell-98-tutorial-sources/code/part6.lhs����������������������������������������������������������0100644�0001064�0000062�00000004455�06774446522�017110� 0����������������������������������������������������������������������������������������������������ustar �jcp�����������������������������ftp��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Gentle Introduction to Haskell 98, Online Supplement Part 5 Covers Sections 2.5.1, 2.5.2 > module Part6() where Section: 2.5.1 List Comprehensions and Arithmetic Sequences Warning: brackets in Haskell are used in three different sorts of expressions: lists, as in [a,b,c], sequences (distinguished by the ..), as in [1..2], and list comprehensions (distinguished by the bar: |), as in [x+1 | x <- xs, x > 1]. Before list comprehensions, consider sequences: > e1 :: [Int] > e1 = [1..10] -- Step is 1 > e2 :: [Int] > e2 = [1,3..10] -- Step is 3 - 1 > e3 :: [Int] > e3 = [1,-1.. -10] -- The space before - is necessary! > e4 :: [Char] > e4 = ['a'..'z'] -- This works on chars too We'll avoid infinite sequences like [1..] for now. If you print one, use C-c i to interrupt the Haskell program. List comprehensions are very similar to nested loops. They return a list of values generated by the expression inside the loop. The filter expressions are similar to conditionals in the loop. This function does nothing at all! It just scans through a list and copies it into a new one. > doNothing :: [a] -> [a] > doNothing l = [x | x <- l] Adding a filter to the previous function allows only selected elements to be generated. This is similar to what is done in quicksort. > positives :: [Int] -> [Int] > positives l = [x | x <- l, x > 0] > e5 = positives [2,-4,5,6,-5,3] Now the full quicksort function. > quicksort :: [Char] -> [Char] -- Use Char just to be different! > quicksort [] = [] > quicksort (x:xs) = quicksort [y | y <- xs, y <= x] ++ > [x] ++ > quicksort [y | y <- xs, y > x] > e6 = quicksort "Why use Haskell?" Now for some nested loops. Each generator, <-, adds another level of nesting to the loop. The variable introduced by each generator can be used in each following generator; all variables can be used in the generated expression: > e7 :: [(Int,Int)] > e7 = [(x,y) | x <- [1..5], y <- [x..5]] Now add some guards: (the /= function is `not equal') > e8 :: [(Int,Int)] > e8 = [(x,y) | x <- [1..7], x /= 5, y <- [x..8] , x*y /= 12] This is the same as the loop: (going to a psuedo Algol notation) for x := 1 to 7 do if x <> 5 then for y := x to 8 do if x*y <> 12 generate (x,y) Section: 2.5.2 Strings > e9 = "hello" ++ " world" Continued in part7.lhs �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������haskell-98-tutorial-sources/code/part1.lhs����������������������������������������������������������0100644�0001064�0000062�00000020354�06774446522�017077� 0����������������������������������������������������������������������������������������������������ustar �jcp�����������������������������ftp�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Gentle Introduction to Haskell 98, Online Supplement Part 1 Covers Section 2 Introduction This is a programming supplement to `A Gentle Introduction to Haskell', version 98, by Hudak, Peterson, and Fasel. This supplement augments the tutorial by providing executable Haskell programs which you can run and experiment with. All program fragments in the tutorial are found here, as well as other examples not included in the tutorial. You should have a copy of both the `Gentle Introduction' and the Haskell 98 report itself to make full use of this tutorial. Although the `Gentle Introduction' is meant to stand by itself, it is often easier to learn a language through actual use and experimentation than by reading alone. Once you finish this introduction, we recommend that you proceed section by section through the `Gentle Introduction' and after having read each section go back to this online tutorial. You should wait until you have finished the tutorial before attempting to read the report. We suggest that you run this code using Hugs, a small Haskell interpreter. Everything is available for download at haskell.org. This tutorial does not assume any familiarity with Haskell or other functional languages. Throughout the online component of this tutorial, we try to relate Haskell to other programming languages and clarify the written tutorial through additional examples and text. Using Hugs If you are using this with Hugs, here are the commands you will need to use. Start up hugs and change to the directory containing these files using `:cd'. Load each part using `:l part1' (or whatever part is next). Inside each part, just type an expression to evaluate it. The expressions that are meant to be evaluated are e1, e2, and so on so if you type `e1' you will see the result of evaluating e1. You can also type more complex expressions if you want. You may also edit these .lhs files (make a fresh copy of them if you want before you start); if you change the .lhs file you have to type `:r' to reload the file into hugs. If you made any mistakes in the program you'll have to fix them to get the :r to work. Organization of the Online Tutorial This online tutorial is divided into a series of file. Each file covers one or more sections in the written tutorial. Each file is a single Haskell program. Comments in the program contain the text of the online tutorial. To create useful, executable examples of Haskell code, some language constructs need to be revealed well before they are explained in the tutorial. We attempt to point these out when they occur. Some small changes have been made to the examples in the written tutorial; these are usually cosmetic and should be ignored. Don't feel you have to understand everything on a page before you move on -- many times concepts become clearer as you move on and can relate them to other aspect of the language. Each part of the tutorial defines a set of variables. Some of these are named e1, e2, and so on. These `e' variables are the ones which are meant for you to evaluate as you go through the tutorial. Of course you may evaluate any other expressions or variables you wish. The Haskell Report While the report is not itself a tutorial on the Haskell language, it can be an invaluable reference to even a novice user. A very important feature of Haskell is the Prelude. The Prelude is a rather large chunk of Haskell code which is implicitly a part of every Haskell program. Whenever you see functions used which are not defined in the current page, these come from the Prelude. Appendix A of the report lists the entire Prelude; the index has an entry for every function in the Prelude. Looking at the definitions in the Prelude is sometimes necessary to fully understand the programs in this tutorial. Another reason to look at the report is to understand the syntax of Haskell. Appendix B contains the complete syntax for Haskell. The tutorial treats the syntax very informally; the precise details are found only in the report. You are now ready to start the tutorial. Start by reading the `Gentle Introduction' section 1 then proceed through the online tutorial using :l (if you are using hugs) to advance to the next part. You should read about each topic first before turning to the associated programming example in the online tutorial. Section: 2 Values, Types, and Other Goodies This tutorial is written in `literate Haskell'. This style requires that all lines containing Haskell code start with `>'; all other lines are comments and are discarded by the compiler. Appendix C of the report defines the syntax of a literate program. This is the first line of the Haskell program on this page: > module Part1() where Comments at the end of source code lines start with `--'. We use these throughout the tutorial to place explanatory text in the program. All Haskell programs start with a module declaration, as in the previous `module Test(Bool) where'. This can be ignored for now. We will start by defining some identifiers (variables) using equations. You can print out the value of an identifier by typing the name of the identifier you wish to evaluate. Not all definitions are very interesting to print out - by convention, we will use variables e1, e2, ... to denote values that are interesting to print. We will start with some constants as well as their associated type. There are two ways to associate a type with a value: a type declaration and an expression type signature. Here is an equation and a type declaration: > e1 :: Int -- This is a type declaration for the identifier e1 > e1 = 5 -- This is an equation defining e1 You can evaluate the expression e1 and watch the system print `5'. Remember that Hugs evaluates expressions, not definitions. If you type `e1 = 5', a definition, you get an error. Definitions have to be placed in the module. The type declaration for e1 is not really necessary but we will try to always provide type declarations for values to help document the program and to ensure that the system infers the same type we do for an expression. If you change the value for e1 to `True', the program will no longer compile due to the type mismatch. We will briefly mention expression type signatures: these are attached to expressions instead of identifiers. Here are equivalent ways to do the previous definition: > e2 = 5 :: Int > e3 = (2 :: Int) + (3 :: Int) The :: has very low precedence in expressions and should usually be placed in parenthesis. There are two completely separate languages in Haskell: an expression language for values and a type language for type signatures. The type language is used only in the type declarations previously described and declarations of new types, described later. Haskell uses a uniform syntax so that values resemble their type signature as much as possible. However, you must always be aware of the difference between type expressions and value expressions. Here are some of the predefined types Haskell provides: type Value Syntax Type Syntax Small integers Int > e4 :: Int > e4 = 12345 Characters '' Char > e5 :: Char > e5 = 'a' Strings "chars" String > e6 :: String > e6 = "abc" Boolean True, False Bool > e7 :: Bool > e7 = True Floating point Float > e8 :: Float > e8 = 123.456 Homogeneous list [,,...] [] > e9 :: [Int] > e9 = [1,2,3] Tuple (,,...) (,,...) > e10 :: (Char,Int) > e10 = ('b',4) Functional described later domain type -> range type > inc :: Int -> Int -- a function which takes an Int argument and returns Int > inc x = x + 1 -- test this by evaluating `int 4' Here's a few leftover examples from section 2: > e11 = inc (inc 3) -- you could also evaluate `inc (inc 3)' directly Uncomment (by adding removing the --) this next line to see a compile time type error. > -- e12 = 'a'+'b' This is a rather odd error message. Essentially says that there is no way to add characters. If there were, it would be by defining an instance in the class Num (this is where + is defined) for the type Char. Continued in part2.lhs ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������haskell-98-tutorial-sources/code/part3.lhs����������������������������������������������������������0100644�0001064�0000062�00000007416�06774446522�017105� 0����������������������������������������������������������������������������������������������������ustar �jcp�����������������������������ftp��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Gentle Introduction to Haskell 98, Online Supplement Part 3 Covers Section 2.1 Section: 2.2 User-Defined Types > module Part3() where The type Bool is already defined in the Prelude so there is no need to define it here. > data Color = Red | Green | Blue | Indigo | Violet deriving Show The `deriving Show' is necessary if you want to print a Color value. You can now evaluate these expressions. > e1 :: Color > e1 = Red > e2 :: [Color] > e2 = [Red,Blue] It is very important to keep the expression language and the type language in Haskell separated. The data declaration above defines the type constructor Color. This is a nullary constructor: it takes no arguments. Color is found ONLY in the type language - it can not be part of an expression. e1 = Color is meaningless. (Actually, Color could be both a data constructor and a type constructor but we'll ignore this possibility for now). On the other hand, Red, Blue, and so on are (nullary) data constructors. They can appear in expressions and in patterns (described later). The declaration e1 :: Blue would also be meaningless. Data constructors can be defined ONLY in a data declaration. In the next example, Point is a type constructor and Pt is a data constructor. Point takes one argument and Pt takes two. A data constructor like Pt is really just an ordinary function except that it can be used in a pattern. Type signatures can not be supplied directly for data constructors; their typing is completely defined by the data declaration. However, data constructors have a signature just like any variable: Pt :: a -> a -> Point a -- Not valid Haskell syntax That is, Pt is a function which takes two arguments with the same arbitrary type and returns a value containing the two argument values. > data Point a = Pt a a deriving Show > e3 :: Point Float > e3 = Pt 2.0 3.0 > e4 :: Point Char > e4 = Pt 'a' 'b' > e5 :: Point (Point Int) > e5 = Pt (Pt 1 2) (Pt 3 4) > -- e6 = Pt 'a' True -- This is a typing error The individual components of a point do not have names. Let's jump ahead a little so that we can write functions using these data types. Data constructors (Red, Blue, ..., and Pt) can be used in patterns. When more than one equation is used to define a function, pattern matching occurs top down. A function to remove red from a list of colors. > removeRed :: [Color] -> [Color] > removeRed [] = [] > removeRed (Red:cs) = removeRed cs > removeRed (c:cs) = c : removeRed cs -- c cannot be Red at this point > e7 :: [Color] > e7 = removeRed [Blue,Red,Green,Red] Pattern matching is capable of testing equality with a specific color. All equations defining a function must share a common type. A definition such as: foo Red = 1 foo (Pt x y) = x would result in a type error since the argument to foo cannot be both a Color and a Point. Similarly, the right hand sides must also share a common type; a definition such as foo Red = Blue foo Blue = Pt Red Red would also result in a type error. Here are a couple of functions defined on points. > dist :: Point Float -> Point Float -> Float > dist (Pt x1 y1) (Pt x2 y2) = sqrt ((x1-x2)^2 + (y1-y2)^2) > midpoint :: Point Float -> Point Float -> Point Float > midpoint (Pt x1 y1) (Pt x2 y2) = Pt ((x1+x2)/2) ((y1+y2)/2) > p1 :: Point Float > p1 = Pt 1.0 1.0 > p2 :: Point Float > p2 = Pt 2.0 2.0 > e8 :: Float > e8 = dist p1 p2 > e9 :: Point Float > e9 = midpoint p1 p2 The only way to take apart a point is to pattern match. That is, the two values which constitute a point must be extracted by matching a pattern containing the Pt data constructor. Much more will be said about pattern matching later. Haskell prints values in the same syntax used in expressions. Thus Pt 1 2 would print as Pt 1 2 (of course, Pt 1 (1+1) would also print as Pt 1 2). Continued in part4.lhs ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������haskell-98-tutorial-sources/code/part2.lhs����������������������������������������������������������0100644�0001064�0000062�00000007113�06774446522�017076� 0����������������������������������������������������������������������������������������������������ustar �jcp�����������������������������ftp��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Gentle Introduction to Haskell 98, Online Supplement Part 2 Covers Section 2.1 Section: 2.1 Polymorphic Types > module Part2() where The following line allows us to redefine functions in the standard prelude. Ignore this for now. > import Prelude hiding (length,head,tail,null) Start with some sample lists to use in test cases: > list1 :: [Int] > list1 = [1,2,3] > list2 :: [Char] -- This is the really a String > list2 = ['a','b','c'] -- This is the same as "abc"; evaluate list2 and see. > list3 :: [[a]] -- The element type of the inner list is unknown > list3 = [[],[],[],[]] -- so this list can't be printed > list4 :: [Int] > list4 = 1:2:3:4:[] -- Exactly the same as [1,2,3,4]; print it and see. This is the length function. You can test it by evaluating expressions such as `length list1'. Function application is written by simple juxtaposition: `f(x)' in other languages would be `f x' in Haskell. > length :: [a] -> Int > length [] = 0 > length (x:xs) = 1 + length xs Function application has the highest precedence, so 1 + length xs is parsed as 1 + (length xs). In general, you have to surround non-atomic arguments to a function with parens. This includes arguments which are also function applications. For example, f g x is the function f applied to arguments g and x, similar to f(g,x) in other languages. However, f (g x) is f applied to (g x), or f(g(x)), which means something quite different! Be especially careful with infix operators: f x+1 y-2 would be parsed as (f x)+(1 y)-2. This is also true on the left of the `=': the parens around (x:xs) are absolutely necessary. length x:xs would be parsed as (length x):xs. Also be careful with prefix negation, -. The application `f -1' is f-1, not f(-1). Add parens around negative numbers to avoid this problem. Here are some other list functions: > head :: [a] -> a -- returns the first element in a list (same as car in lisp) > head (x:xs) = x > tail :: [a] -> [a] -- removes the first element from a list (same as cdr) > tail (x:xs) = xs > null :: [a] -> Bool > null [] = True > null (x:xs) = False > cons :: a -> [a] -> [a] > cons x xs = x:xs > nil :: [a] > nil = [] Length could be defined using these functions. This is not good Haskell style but does illustrate these other list functions. Haskell programmers feel that the pattern matching style, as used in the previous version of length, is more natural and readable. > length' :: [a] -> Int -- Note that ' can be part of a name > length' x = if null x then 0 else 1 + length' (tail x) A test case for length', cons, and nil > e1 = length' (cons 1 (cons 2 nil)) We haven't said anything about errors yet. Each of the following examples illustrates a potential runtime or compile time error. The compile time error is commented out so that other examples will compile; you can uncomment e2 and see what happens. > -- e2 = cons True False -- Why is this not possible in Haskell? > e3 = tail (tail ['a']) -- What happens if you evaluate this? > e4 = [] -- This is especially mysterious! This last example, e4, is something hard to explain but is often encountered early by novices. We haven't explained yet how the system prints out the expressions you type in - this will wait until later. However, the problem here is that e4 has the type [a]. The printer for the list datatype is complaining that it needs to know a specific type for the list elements even though the list has no elements! This can be avoided by giving e4 a type such as [Int]. (To further confuse you, try giving e4 the type [Char] and see what happens.) Continued in part3.lhs �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������haskell-98-tutorial-sources/code/index.html���������������������������������������������������������0100644�0001064�0000062�00000002544�06774446522�017336� 0����������������������������������������������������������������������������������������������������ustar �jcp�����������������������������ftp�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Haskell code for the Gentle Intro 98

    Haskell code for the Gentle Intro 98

    haskell-98-tutorial-sources/code/part4.lhs0100644000106400000620000000343406774446522017102 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 4 Covers Section 2.3 Section: 2.3 Recursive Types > module Part4() where > data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show The following typings are implied by this declaration. As before, this is not valid Haskell syntax. Leaf :: a -> Tree a Branch :: Tree a -> Tree a -> Tree a > fringe :: Tree a -> [a] > fringe (Leaf x) = [x] > fringe (Branch left right) = fringe left ++ fringe right The following trees can be used to test functions: > tree1 :: Tree Int > tree1 = Branch (Leaf 1) (Branch (Branch (Leaf 2) (Leaf 3)) (Leaf 4)) > tree2 :: Tree Int > tree2 = Branch (Branch (Leaf 3) (Leaf 1)) (Branch (Leaf 4) (Leaf 1)) > tree3 :: Tree Int > tree3 = Branch tree1 tree2 Try evaluating `fringe tree1' and others. Here's another tree function: > twist :: Tree a -> Tree a > twist (Branch left right) = Branch right left > twist x = x -- This equation only applies to leaves Here's a function which compares two trees to see if they have the same shape. Note the signature: the two trees need not contain the same type of values. > sameShape :: Tree a -> Tree b -> Bool > sameShape (Leaf x) (Leaf y) = True > sameShape (Branch l1 r1) (Branch l2 r2) = sameShape l1 l2 && sameShape r1 r2 > sameShape x y = False -- One is a branch, the other is a leaf The && function is a boolean AND function. The entire pattern on the left hand side must match in order for the right hand side to be evaluated. The first clause requires both arguments to be a leaf' otherwise the next equation is tested. The last clause will always match: the final x and y match both leaves and branches. This compares a tree of integers to a tree of booleans. > e1 = sameShape tree1 (Branch (Leaf True) (Leaf False)) Continued in part5.lhs haskell-98-tutorial-sources/code/index.html~0100644000106400000620000000014706774446522017531 0ustar jcpftp Haskell code for the Gentle Intro 98

    Haskell code for the Gentle Intro 98

    haskell-98-tutorial-sources/code/part5.lhs0100644000106400000620000000531006774446522017076 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 5 Covers Sections 2.4, 2.5, 2.6 Section: 2.4 Type Synonyms > module Part5() where Since type synonyms are part of the type language only, it's hard to write a program which shows what they do. Essentially, they are like macros for the type language. They can be used interchangeably with their definition: > e1 :: String > e1 = "abc" > e2 :: [Char] -- No different than String > e2 = e1 In the written tutorial the declaration of `Addr' is a data type declaration, not a synonym declaration. This shows that the data type declaration as well as a signature can reference a synonym. Section: 2.5 Built-in Types Tuples are an easy way of grouping a set of data values. Here are a few tuples. Note the consistancy in notation between the values and types. > e3 :: (Bool,Int) > e3 = (True,4) > e4 :: (Char,[Int],Char) > e4 = ('a',[1,2,3],'b') Here's a function which returns the second component of a 3 tuple. > second :: (a,b,c) -> b > second (a,b,c) = b Try out `second e3' and `second e4' - what happens? Each different size of tuple is a completely distinct type. There is no general way to append two arbitrary tuples or randomly select the i'th component of an arbitrary tuple. Here's a function built using 2-tuples to represent intervals. Use a type synonym to represent homogeneous 2 tuples > type Interval a = (a,a) > containsInterval :: Interval Int -> Interval Int -> Bool > containsInterval (xmin,xmax) (ymin,ymax) = xmin <= ymin && xmax >= ymax > p1 :: Interval Int > p1 = (2,3) > p2 :: Interval Int > p2 = (1,4) > e5 = containsInterval p1 p2 > e6 = containsInterval p2 p1 Here's a type declaration for a type isomorphic to lists: > data List a = Nil | Cons a (List a) deriving Show Except for the notation, this is completely equivalent to ordinary lists in Haskell. > length' :: List a -> Int > length' Nil = 0 > length' (Cons x y) = 1 + length' y > e7 = length' (Cons 'a' (Cons 'b' (Cons 'c' Nil))) It is hard to demonstrate much about the `non-specialness' of built-in types. However, here is a brief summary: Numbers and characters, such as 1, 2.2, or 'a', are the same as nullary type constructors. Lists have a special type constructor, [a] instead of List a, and an odd looking data constructor, []. The other data constructor, :, is not `unusual', syntactically speaking. The notation [x,y] is just syntax for x:y:[] and "abc" for 'a' : 'b' : 'c' : []. Tuples use a special syntax. In a type expression, a 2 tuple containing types a and be would be written (a,b) instead of using a prefix type constructor such as Tuple2 a b. This same notation is used to build tuple values: (1,2) would construct a 2 tuple containing the values 1 and 2. haskell-98-tutorial-sources/code/part7.lhs0100644000106400000620000000423506774446522017105 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 7 Covers Sections 3, 3.1 > module Part7() where > import Prelude hiding (map) Section: 3 Functions > add :: Int -> Int -> Int > add x y = x+y > e1 :: Int > e1 = add 1 2 This Int -> Int is the latter part of the signature of add: add :: Int -> (Int -> Int) > inc :: Int -> Int > inc = add 1 > e2 :: Int > e2 = inc 3 > map :: (a->b) -> [a] -> [b] > map f [] = [] > map f (x:xs) = f x : (map f xs) > e3 :: [Int] > e3 = map (add 1) [1,2,3] This next definition is the equivalent to e3 > e4 :: [Int] > e4 = map inc [1,2,3] Heres a more complex example. Define flist to be a list of functions: > flist :: [Int -> Int] > flist = map add [1,2,3] This returns a list of functions which add 1, 2, or 3 to their input. Haskell should print flist as something like [<>,<>,<>] Now, define a function which takes a function and returns its value when applied to the constant 1: > applyTo1 :: (Int -> a) -> a > applyTo1 f = f 1 > e5 :: [Int] > e5 = map applyTo1 flist -- Apply each function in flist to 1 If you want to look at how the type inference works, figure out how the signatures of map, applyTo1, and flist combine to yield [Int]. Section: 3.1 Lambda Abstractions The symbol \ is like `lambda' in lisp or scheme. Anonymous functions are written as \ arg1 arg2 ... argn -> body Instead of naming every function, you can code it inline with this notation: > e6 = map (\f -> f 1) flist Be careful with the syntax here. \x->\y->x+y parses as \ x ->\ y -> x + y. The ->\ is all one token. Use spaces!! This is identical to e5 except that the applyTo1 function has no name. Function arguments on the left of an = are the same as lambda on the right: > add' = \x y -> x+y -- identical to add > inc' = \x -> x+1 -- identical to inc As with ordinary function, the parameters to anonymous functions can be patterns: > e7 :: [Int] > e7 = map (\(x,y) -> x+y) [(1,2),(3,4),(5,6)] Functions defined by more than one equation, like map, cannot be converted to anonymous lambda functions quite as easily - a case statement is also required. This is discussed later. Continued in part8.lhs haskell-98-tutorial-sources/code/part8.lhs0100644000106400000620000000414506774446522017106 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 8 Covers Sections 3.2, 3.2.1, 3.2.2 > module Part8() where > import Prelude hiding ((++),(.)) Section: 3.2 Infix operators Haskell has both identifiers, like `x', and operators, like `+'. These are just two different types of syntax for variables. However, operators are by default used in infix notation. Briefly, identifiers begin with a letter and may have numbers, _, and ' in them: x, xyz123, x'', xYz'_12a. The case of the first letter distinguishes variables from data constructors (or type variables from type constructors). An operator is a string of symbols, where :!#$%&*+./<=>?@\^| are all symbols. If the first character is : then the operator is a data constructor; otherwise it is an ordinary variable operator. The - and ~ characters may start a symbol but cannot be used after the first character. This allows a*-b to parse as a * - b instead of a *- b. Operators can be converted to identifiers by enclosing them in parens. This is required in signature declarations. Operators can be defined as well as used in the infix style: > (++) :: [a] -> [a] -> [a] > [] ++ y = y > (x:xs) ++ y = x : (xs ++ y) Table 2 (Page 54) of the report is invaluable for sorting out the precedences of the many predefined infix operators. > e1 = "Foo" ++ "Bar" This is the same function without operator syntax > appendList :: [a] -> [a] -> [a] > appendList [] y = y > appendList (x:xs) y = x : appendList xs y > (.) :: (b -> c) -> (a -> b) -> (a -> c) > f . g = \x -> f (g x) > add1 :: Int -> Int > add1 x = x+1 > e2 = (add1 . add1) 3 Section: 3.2.1 Sections Sections are a way of creating unary functions from infix binary functions. When a parenthesized expression starts or ends in an operator, it is a section. Another definition of add1: > add1' :: Int -> Int > add1' = (+ 1) > e3 = add1' 4 Here are a few section examples: > e4 = map (++ "abc") ["x","y","z"] > e5 = map ("abc" ++) ["x","y","z"] Section: 3.2.2 Fixity Declarations We'll avoid any demonstration of fixity declarations. The Prelude contains numerous examples. Continued in part9.lhs haskell-98-tutorial-sources/code/part9.lhs0100644000106400000620000000665706774446522017121 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 9 Covers Sections 3.3, 3.4, 3.5 > module Part9() where > import Prelude hiding (take,zip) Section: 3.3 Functions are Non-strict Observing lazy evaluation can present difficulties. The essential question is `does an expression get evaluated?'. While in theory using a non-terminating computation is the way evaluation issues are examined, we need a more practical approach. In expressions, Haskell uses `error' to denote bottom. Evaluation of `error' will halt execution and print the attached error message. The error function can be used to create stub functions for program components which have not been written yet or as a value to insert into data structures where a data value is required but should never be used. > e1 :: Bool -- This can be any type at all! > e1 = error "e1" -- evaluate this and see what happens. > const1 :: a -> Int > const1 x = 1 > e2 :: Int > e2 = const1 (error "e2") -- The bottom (the error function) is not > -- needed and will thus not be evaluated. Section: 3.4 "Infinite" Data Structures Data structures are constructed lazily. A constructor like : will not evaluate its arguments until they are demanded. All demands arise from the need to print the result of the computation -- components not needed to compute the printed result will not be evaluated. > list1 :: [Int] > list1 = (1:error "list1") > e3 = head list1 -- does not evaluate the error > e4 = tail list1 -- does evaluate error Some infinite data structures. Don't print these! If you do, you will need to interrupt the system or kill the Haskell process. > ones :: [Int] > ones = 1 : ones > numsFrom :: Int -> [Int] > numsFrom n = n : numsFrom (n+1) An alternate numsFrom using series notation: > numsFrom' :: Int -> [Int] > numsFrom' n = [n..] > squares :: [Int] > squares = map (^2) (numsFrom 0) Before we start printing anything, we need a function to truncate these infinite lists down to a more manageable size. The `take' function extracts the first k elements of a list: > take :: Int -> [a] -> [a] > take 0 x = [] -- two base cases: k = 0 > take k [] = [] -- or the list is empty > take k (x:xs) = x : take (k-1) xs now some printable lists: > e5 :: [Int] > e5 = take 5 ones > e6 :: [Int] > e6 = take 5 (numsFrom 10) > e7 :: [Int] > e7 = take 5 (numsFrom' 0) > e8 :: [Int] > e8 = take 5 squares zip is a function which turns two lists into a list of 2 tuples. If the lists are of differing sizes, the result is as long as the shortest list. > zip (x:xs) (y:ys) = (x,y) : zip xs ys > zip xs ys = [] -- one of the lists is [] > e9 :: [(Int,Int)] > e9 = zip [1,2,3] [4,5,6] > e10 :: [(Int,Int)] > e10 = zip [1,2,3] ones > fib :: [Int] > fib = 1 : 1 : [x+y | (x,y) <- zip fib (tail fib)] > e11 = take 10 fib This can be done without the list comprehension: > fib' :: [Int] > fib' = 1 : 1 : map (\(x,y) -> x+y) (zip fib (tail fib)) This could be written even more cleanly using a map function which maps a binary function over two lists at once. This is in the Prelude and is called zipWith. > fib'' :: [Int] > fib'' = 1 : 1 : zipWith (+) fib (tail fib) For more examples using infinite structures look in the demo files that come with Yale Haskell. Both the pascal program and the primes program use infinite lists. Section: 3.5 The Error Function Too late - we already used it! Continued in part10.lhs haskell-98-tutorial-sources/code/part10.lhs0100644000106400000620000000544206774446522017160 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 10 Covers Sections 4, 4.1, 4.2 > module Part10() where > import Prelude hiding (take,(^)) Section: 4 Case Expressions and Pattern Matching Now for details of pattern matching. We use [Int] instead of [a] since the only value of type [a] is []. > contrived :: ([Int], Char, (Int, Float), String, Bool) -> Bool > contrived ([], 'b', (1, 2.0), "hi", True) = False > contrived x = True -- add a second equation to avoid runtime errors > e1 :: Bool > e1 = contrived ([], 'b', (1, 2.0), "hi", True) > e2 :: Bool > e2 = contrived ([1], 'b', (1, 2.0), "hi", True) Contrived just tests its input against a big constant. Linearity in pattern matching implies that patterns can only compare values with constants. The following is not valid Haskell: member x [] = False member x (x:ys) = True -- Invalid since x appears twice member x (y:ys) = member x ys > f :: [a] -> [a] > f s@(x:xs) = x:s > f _ = [] > e3 = f "abc" Another use of _: > middle :: (a,b,c) -> b > middle (_,x,_) = x > e4 :: Char > e4 = middle (True, 'a', "123") > (^) :: Int -> Int -> Int > x ^ 0 = 1 > x ^ (n+1) = x*(x^n) > e5 :: Int > e5 = 3^3 > e6 :: Int > e6 = 4^(-2) -- Notice the behavior of the + pattern on this one Section: 4.1 Pattern Matching Semantics Here's an extended example to illustrate the left -> right, top -> bottom semantics of pattern matching. > foo :: (Int,[Int],Int) -> Int > foo (1,[2],3) = 1 > foo (2,(3:_),3) = 2 > foo (1,_,3) = 3 > foo _ = 4 > e7 = foo (1,[],3) > e8 = foo (1,error "in e8",3) > e9 = foo (1,1:(error "in e9"),3) > e10 = foo (2,error "in e10",2) > e11 = foo (3,error "in e11 (second)",error "in e11 (third)") Now add some guards: > sign :: Int -> Int > sign x | x > 0 = 1 > | x == 0 = 0 > | x < 0 = -1 > e12 = sign 3 The last guard is often `True' to catch all other cases. The identifier `otherwise' is defined as True for use in guards: > max' :: Int -> Int -> Int > max' x y | x > y = x > | otherwise = y Guards can refer to any variables bound by pattern matching. When no guard is true, pattern matching resumes at the next equation. Guards may also refer to values bound in an associated where declaration. > inOrder :: [Int] -> Bool > inOrder (x1:x2:xs) | x1 <= x2 = True > inOrder _ = False > e13 = inOrder [1,2,3] > e14 = inOrder [2,1] Section: 4.2 An Example > take :: Int -> [a] -> [a] > take 0 _ = [] > take _ [] = [] > take (n+1) (x:xs) = x:take n xs > take' :: Int -> [a] -> [a] > take' _ [] = [] > take' 0 _ = [] > take' (n+1) (x:xs) = x:take' n xs > e15, e16, e17, e18 :: [Int] > e15 = take 0 (error "e15") > e16 = take' 0 (error "e16") > e17 = take (error "e17") [] > e18 = take' (error "e18") [] Continued in part11.lhs haskell-98-tutorial-sources/code/part11.lhs0100644000106400000620000000636406774446522017165 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 11 Covers Sections 4.3, 4.4, 4.5, 4.6 > module Part11() where > import Prelude hiding (take) Section: 4.3 Case Expressions The function `take' using a case statement instead of multiple equations: > take :: Int -> [a] -> [a] > take m ys = case (m,ys) of > (0 ,_) -> [] > (_ ,[]) -> [] > (n+1,x:xs) -> x : take n xs The function take using if then else. We can also eliminate the n+k pattern just for fun. The original version of take is much easier to read! > take' :: Int -> [a] -> [a] > take' m ys = if m == 0 then [] else > if null ys then [] else > if m > 0 then head ys : take (m-1) (tail ys) > else error "m < 0" Section: 4.4 Lazy Patterns Before the client-server example, here is a contrived example of lazy patterns. The first version will fail to pattern match whenever the the first argument is []. The second version will always pattern match initially but x will fail if used when the list is []. > nonlazy :: [Int] -> Bool -> [Int] > nonlazy (x:xs) isNull = if isNull then [] else [x] > e1 = nonlazy [1,2] False > e2 = nonlazy [] True > e3 = nonlazy [] False This version will never fail the initial pattern match > lazy :: [Int] -> Bool -> [Int] > lazy ~(x:xs) isNull = if isNull then [] else [x] > e4 = lazy [1,2] False > e5 = lazy [] True > e6 = lazy [] False The server - client example is a little hard to demonstrate. We'll avoid the initial version which loops. Here is the version with irrefutable patterns. > type Response = Int > type Request = Int > client :: Request -> [Response] -> [Request] > client init ~(resp:resps) = init : client (next resp) resps > server :: [Request] -> [Response] > server (req : reqs) = process req : server reqs Next maps the response from the previous request onto the next request > next :: Response -> Request > next resp = resp Process maps a request to a response > process :: Request -> Response > process req = req+1 > requests :: [Request] > requests = client 0 responses > responses :: [Response] > responses = server requests > e7 = take 5 responses The lists of requests and responses are infinite - there is no need to check for [] in this program. These lists correspond to streams in other languages. Here is fib again: > fib :: [Int] > fib@(_:tfib) = 1 : 1 : [ a+b | (a,b) <- zip fib tfib] > e8 = take 10 fib Section: 4.5 Lexical Scoping and Nested Forms One thing that is important to note is that the order of the definitions in a program, let expression, or where clauses is completely arbitrary. Definitions can be arranged 'top down' or `bottom up' without changing the program. > e9 = let y = 2 :: Float > f x = (x+y)/y > in f 1 + f 2 > f :: Int -> Int -> String > f x y | y > z = "y > x^2" > | y == z = "y = x^2" > | y < z = "y < x^2" > where > z = x*x > e10 = f 2 5 > e11 = f 2 4 Section: 4.6 Layout There's nothing much to demonstrate here. We have been using layout all through the tutorial. The main thing is to be careful line up the first character of each definition. For example, if you change the indentation of the definition of f in e9 you will get a parse error. Continued in part12.lhs haskell-98-tutorial-sources/code/part12.lhs0100644000106400000620000000640406774446522017161 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 12 Covers Section 5 > module Part12() where > import Prelude hiding (elem) Section: 5 Type Classes Names in the basic class structure of Haskell cannot be hidden (they are in PreludeCore) so we have to modify the names used in the tutorial. Here is a new Eq class: > class Eq' a where > eq :: a -> a -> Bool Now we can define elem using eq from above: > elem :: (Eq' a) => a -> [a] -> Bool > x `elem` [] = False > x `elem` (y:ys) = x `eq` y || x `elem` ys Before this is of any use, we need to admit some types to Eq' > instance Eq' Int where > x `eq` y = abs (x-y) < 3 -- Let's make this `nearly equal' just for fun > instance Eq' Float where > x `eq` y = abs (x-y) < 0.1 > list1 :: [Int] > list1 = [1,5,9,23] > list2 :: [Float] > list2 = [0.2,5.6,33,12.34] > e1 = 2 `elem` list1 > e2 = 100 `elem` list1 > e3 = 0.22 `elem` list2 Watch out! Integers in Haskell are overloaded - without a type signature to designate an integer as an Int, expressions like 3 `eq` 3 will be ambiguous. Now to add the tree type: > data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show > instance (Eq' a) => Eq' (Tree a) where > (Leaf a) `eq` (Leaf b) = a `eq` b > (Branch l1 r1) `eq` (Branch l2 r2) = (l1 `eq` l2) && (r1 `eq` r2) > _ `eq` _ = False > tree1,tree2 :: Tree Int > tree1 = Branch (Leaf 1) (Leaf 2) > tree2 = Branch (Leaf 2) (Leaf 1) > e4 = tree1 `eq` tree2 Now make a new class with Eq' as a super class: > class (Eq' a) => Ord' a where > lt,le :: a -> a -> Bool -- lt and le are operators in Ord' > x `le` y = x `eq` y || x `lt` y -- This is a default for le The typing of lt & le is le,lt :: (Ord' a) => a -> a -> Bool This is identical to le,lt :: (Eq' a,Ord' a) => a -> a -> Bool Make Int an instance of Ord': > instance Ord' Int where > x `lt` y = x < y+1 > i :: Int -- Avoid ambiguity > i = 3 > e5 :: Bool > e5 = i `lt` i Some constraints on instance declarations: A program can never have more than one instance declaration for a given combination of data type and class. If a type is declared to be a member of a class, it must also be declared in all superclasses of that class. An instance declaration does not need to supply a method for every operator in the class. When a method is not supplied in an instance declaration and no default is present in the class declaration, a runtime error occurs if the method is invoked. You must supply the correct context for an instance declaration -- this context is not inferred automatically. This definition of Functor is in the Prelude: class Functor f where fmap :: (a -> b) -> f a -> f b -- a generalized map function This makes Tree an instance of Functor. > instance Functor Tree where > fmap f (Leaf x) = Leaf (f x) > fmap f (Branch t1 t2) = Branch (fmap f t1) (fmap f t2) > e6 = fmap (+1) tree1 We can also make 2-tuples an instance of Functor: > instance Functor ((,) a) where > fmap f (x,y) = (x,f y) > e7 = fmap (+1) (1,2) Note that these are a kind errors: > -- instance Functor (,) > -- instance Functor Bool The error message from Hugs isn't very useful but if you use :set +k then you will see a better message. Continued in part13.lhs haskell-98-tutorial-sources/code/part13.lhs0100644000106400000620000000420006774446522017152 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 13 Covers Section 6.1, 6.2, 6.3 > module Part13() where Section 6.1 Example from the tutorial. Note that newtype supports deriving in the same manner as data. We also need to derive a Eq instance for Natural since the definition of Num has Eq as a superclass. The Num instance of Natural allows the use of integer constants such as 1 as Naturals. > newtype Natural = MakeNatural Integer deriving (Show, Eq) > toNatural :: Integer -> Natural > toNatural x | x < 0 = error "Can't create negative naturals!" > | otherwise = MakeNatural x > fromNatural :: Natural -> Integer > fromNatural (MakeNatural i) = i > instance Num Natural where > fromInteger = toNatural > x + y = toNatural (fromNatural x + fromNatural y) > x - y = let r = fromNatural x - fromNatural y in > if r < 0 then error "Unnatural subtraction" > else toNatural r > x * y = toNatural (fromNatural x * fromNatural y) > e1 :: Natural > e1 = toNatural 1 > e2 :: Natural > e2 = 1 > e3 :: Natural > e3 = 1 + 1 > e4 :: Natural > e4 = (3 - 4) + 3 Section 6.2 > data Point = Pt {pointx, pointy :: Float} deriving Show > absPoint :: Point -> Float > absPoint p = sqrt (pointx p * pointx p + pointy p * pointy p) > e5 :: Point > e5 = Pt {pointx = 1, pointy = 2} > e6 :: Float > e6 = absPoint e5 > e7 :: Float > e7 = pointx e5 > e8 :: Point > e8 = e5 {pointx = 4} > data T = C1 {f :: Int, g :: Float} > | C2 {f :: Int, h :: Bool} deriving Show > e9 :: T > e9 = C1 {f = 1, g = 2} > e10 :: T > e10 = C2 {f = 3, h = False} > e11 :: Int > e11 = f e9 > e12 :: Int > e12 = f e10 > e13 :: Float > e13 = g e10 Section 6.3 Here is a definition of head-strict lists: the head of each list is evaluated when the list is constructed. > data HList a = Cons !a (HList a) | Nil deriving Show > hd (Cons x y) = x > tl (Cons x y) = y If the "!" is removed then e17 no longer is an error. > e14 :: HList Bool > e14 = True `Cons` (error "e14" `Cons` Nil) > e15, e16 :: Bool > e15 = hd e14 > e16 = hd (tl e14) > e17 :: HList Bool > e17 = tl (tl (e14)) Continued in part14.lhs haskell-98-tutorial-sources/code/part15.lhs0100644000106400000620000000474306774446522017170 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 15 Covers Section 7.3, 7.3, 7.5 > module Part15() where > import IO Section 7.3 To experiment with I/O errors, we need to get a bit creative. Generating an error is generally OS specific so instead we will use errors that are directly under user control. The function userError :: String -> IOError generates an error value and the function ioeGetErrorString :: IOError -> String gets the string out of an error. This version of getChar that raises an error when an @ or ? is entered: > getCharE :: IO Char > getCharE = do c <- getChar > case c of > '@' -> ioError (userError "@") > '?' -> ioError (userError "?") > _ -> return c Using this extended getChar we can build getChar' to catch only @ There is currently a bug in Hugs - if this gets fixed change the definition is isAtError. > isAtError :: IOError -> Bool > isAtError e = ioeGetErrorString e == "User error: @" -- for bug in hugs > -- isAtError e = ioeGetErrorString e == "@" -- Should be this > getChar' :: IO Char > getChar' = getCharE `catch` atHandler where > atHandler e = if isAtError e then return '\n' else ioError e > getLine' :: IO String > getLine' = catch getLine'' (\err -> return ("Error: " ++ show err)) > where > getLine'' = do c <- getChar' > if c == '\n' then return "" > else do l <- getLine' > return (c:l) Observe the behavior when you enter @ or ? > e1 = getCharE Now try lines with @ and ? in them. > e2 = do l <- getLine' > putStrLn l Section 7.4 You will have to set up some files to play with if you want to try this one. > e3 = do fromHandle <- getAndOpenFile "Copy from: " ReadMode > toHandle <- getAndOpenFile "Copy to: " WriteMode > contents <- hGetContents fromHandle > hPutStr toHandle contents > hClose toHandle > putStr "Done." > getAndOpenFile :: String -> IOMode -> IO Handle > getAndOpenFile prompt mode = > do putStr prompt > name <- getLine > catch (openFile name mode) > (\_ -> do putStrLn ("Cannot open "++ name ++ "\n") > getAndOpenFile prompt mode) > Continued in part16.lhs haskell-98-tutorial-sources/code/part14.lhs0100644000106400000620000000336706774446522017170 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 14 Covers Section 7, 7.1, 7.2 > module Part14 where > import Prelude hiding (putStr, getLine, sequence_) > import IO (isEOFError) Both putStr and getLine are actually in the prelude. Section: 7 I/O Section 7.1 The I/O monad divides the Haskell world into values and actions. So far, we have only used values but now we need to execute actions. Hugs looks at the type of an expression typed at the prompt. If the type is an IO type, the expression is assumed to be an action and the action is invoked. If the type is not IO t (for any t), then the expression value is printed. > e1 = do c <- getChar > putChar c > ready = do c <- getChar > return (c == 'y') The print function converts a value to a string (using the Show class) and prints it with a newline at the end. > e2 = do r <- ready > print r You can't put the call to ready and print in the same expression. This would be wrong: e2 = print (ready) > getLine :: IO String > getLine = do c <- getChar > if c == '\n' > then return "" > else do l <- getLine > return (c:l) putStrLn prints a string and adds a newline at the end. > e3 = do putStr "Type Something: " > str <- getLine > putStrLn ("You typed: " ++ str) Section 7.2 > todoList :: [IO ()] > todoList = [putChar 'a', > do putChar 'b' > putChar 'c', > do c <- getChar > putChar c] > sequence_ :: [IO ()] -> IO () > sequence_ = foldr (>>) (return ()) > e4 = sequence_ todoList > putStr :: String -> IO () > putStr s = sequence_ (map putChar s) > e5 = putStr "Hello World" Continued in part15.lhs haskell-98-tutorial-sources/code/part16.lhs0100644000106400000620000001040006774446522017154 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 16 Covers Section 8, 8.1, 8.2, 8.3 > module Part16() where Section: 8.1 Equality and Ordered Classes Section: 8.2 Enumeration and Index Classes No examples are provided for 5.1 or 5.2. The standard Prelude contains many instance declarations which illustrate the Eq, Ord, and Enum classes. Section: 8.3 The Read and Show Classes This is the slow showTree. The `show' function is part of the Text class and works with all the built-in types. The context `Text a' arises from the call to show for leaf values. > data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show > showTree :: (Show a) => Tree a -> String > showTree (Leaf x) = show x > showTree (Branch l r) = "<" ++ showTree l ++ "|" ++ showTree r ++ ">" > tree1 :: Tree Int > tree1 = Branch (Leaf 1) (Branch (Leaf 3) (Leaf 6)) > e1 = showTree tree1 Now the improved showTree; shows is already defined for all built in types. > showsTree :: Show a => Tree a -> String -> String > showsTree (Leaf x) s = shows x s > showsTree (Branch l r) s = '<' : showsTree l ('|' : showsTree r ('>' : s)) > e2 = showsTree tree1 "" The final polished version. ShowS is predefined in the Prelude so we don't need it here. > showsTree' :: Show a => Tree a -> ShowS > showsTree' (Leaf x) = shows x > showsTree' (Branch l r) = ('<' :) . showsTree' l . ('|' :) . > showsTree' r . ('>' :) > e3 = showsTree' tree1 "" In the Prelude, there is a showChar function that can be used instead of ('<' :). Now for the reading function. Again, ReadS is predefined and reads works for all built-in types. The generators in the list comprehensions are patterns: p <- l binds pattern p to successive elements of l which match p. Elements not matching p are skipped. > readsTree :: (Read a) => ReadS (Tree a) > readsTree ('<':s) = [(Branch l r, u) | (l, '|':t) <- readsTree s, > (r, '>':u) <- readsTree t ] > readsTree s = [(Leaf x,t) | (x,t) <- reads s] > e4 :: [(Int,String)] > e4 = reads "5 golden rings" > e5 :: [(Tree Int,String)] > e5 = readsTree "<1|<2|3>>" > e6 :: [(Tree Int,String)] > e6 = readsTree "<1|2" > e7 :: [(Tree Int,String)] > e7 = readsTree "<1|<<2|3>|<4|5>>> junk at end" Before we do the next readTree, let's play with the lex function. > e8 :: [(String,String)] > e8 = lex "foo bar bletch" Here's a function to completely lex a string. This does not handle lexical ambiguity - lex would return more than one possible lexeme when an ambiguity is encountered and the patterns used here would not match. > lexAll :: String -> [String] > lexAll s = case lex s of > [("",_)] -> [] -- lex returns an empty token if none is found > [(token,rest)] -> token : lexAll rest > e9 = lexAll "lexAll :: String -> [String]" > e10 = lexAll "<1|>" Finally, the complete reader. This is not sensitive to white space as were the previous versions. When you derive the Show class for a data type the reader generated automatically is similar to this in style. > readsTree' :: (Read a) => ReadS (Tree a) > readsTree' s = [(Branch l r, x) | ("<", t) <- lex s, > (l, u) <- readsTree' t, > ("|", v) <- lex u, > (r, w) <- readsTree' v, > (">", x) <- lex w ] > ++ > [(Leaf x, t) | (x, t) <- reads s] When testing this program, you must make sure the input conforms to Haskell lexical syntax. If you remove spaces between | and < or > they will lex as a single token as you should have noticed with e10. > e11 :: [(Tree Int,String)] > e11 = readsTree' "<1 | <2 | 3> >" > e12 :: [(Tree Bool,String)] > e12 = readsTree' "" Finally, here is a simple version of read for trees only: > read' :: (Read a) => String -> (Tree a) > read' s = case (readsTree' s) of > [(tree,"")] -> tree -- Only one parse, no junk at end > [] -> error "Couldn't parse tree" > [_] -> error "Crud after the tree" -- unread chars at end > _ -> error "Ambiguous parse of tree" > e13 :: Tree Int > e13 = read' "foo" > e14 :: Tree Int > e14 = read' "< 1 | < 2 | 3 > >" > e15 :: Tree Int > e15 = read' "3 xxx" Continued in part17.lhs haskell-98-tutorial-sources/code/part17.lhs0100644000106400000620000000243406774446522017165 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 17 Covers Section 8.4 Section: 8.4 Derived Instances We have actually been using the derived Show instances all along for printing out trees and other structures we have defined. The code in the tutorial for the Eq and Ord instance of Tree is created implicitly by the deriving clause so there is no need to write it here. > data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving (Eq,Ord,Show) Now we can fire up both Eq and Ord functions for trees: > tree1, tree2, tree3, tree4 :: Tree Int > tree1 = Branch (Leaf 1) (Leaf 3) > tree2 = Branch (Leaf 1) (Leaf 5) > tree3 = Leaf 4 > tree4 = Branch (Branch (Leaf 4) (Leaf 3)) (Leaf 5) > e1 = tree1 == tree1 > e2 = tree1 == tree2 > e3 = tree1 < tree2 > quicksort :: Ord a => [a] -> [a] > quicksort [] = [] > quicksort (x:xs) = quicksort [y | y <- xs, y <= x] ++ > [x] ++ > quicksort [y | y <- xs, y > x] > e4 = quicksort [tree1,tree2,tree3,tree4] Now for Enum: > data Day = Sunday | Monday | Tuesday | Wednesday | Thursday | > Friday | Saturday deriving (Show,Eq,Ord,Enum) > e5 = quicksort [Monday,Saturday,Friday,Sunday] > e6 = [Wednesday .. Friday] > e7 = [Monday, Wednesday ..] > e8 = [Saturday, Friday ..] Continued in part18.lhs haskell-98-tutorial-sources/code/part18.lhs0100644000106400000620000001315506774446522017170 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 18 Covers Sections 9, 9.1, 9.2, 9.3 Section 9.1 Monadic Classes Section 9.2 Built-in Monads > module Part18() where > e1 = [(x,y) | x <- [1,2,3] , y <- [1,2,3], x /= y] > e2 = do x <- [1,2,3] > y <- [1,2,3] > True <- return (x /= y) > return (x,y) > e3 = [1,2,3] >>= (\ x -> [1,2,3] >>= (\y -> return (x/=y) >>= > (\r -> case r of True -> return (x,y) > _ -> fail ""))) > mvLift2 :: (a -> b -> c) -> [a] -> [b] -> [c] > mvLift2 f x y = do x' <- x > y' <- y > return (f x' y') > e4 = mvLift2 (+) [1,3] [10,20,30] > e5 = mvLift2 (\a b -> [a,b]) "ab" "cd" > e6 = mvLift2 (*) [1,2,4] [] A quick example using Maybe: first, generalize mvLift2 to all monads: > lift2' :: Monad m => (a -> b -> c) -> m a -> m b -> m c > lift2' f x y = do x' <- x > y' <- y > return (f x' y') > e7 = lift2' (+) (Just 1) (Just 2) > e8 = lift2' (+) (Just 1) Nothing Section 9.3 > type S = Int > data SM a = SM (S -> (a,S)) -- The monadic type > instance Monad SM where > -- defines state propagation > SM c1 >>= fc2 = SM (\s0 -> let (r,s1) = c1 s0 > SM c2 = fc2 r in > c2 s1) > return k = SM (\s -> (k,s)) > -- extracts the state from the monad > readSM :: SM S > readSM = SM (\s -> (s,s)) > -- extracts the state from the monad > updateSM :: (S -> S) -> SM () -- alters the state > updateSM f = SM (\s -> ((), f s)) > -- run a computation in the SM monad > runSM :: S -> SM a -> (a,S) > runSM s0 (SM c) = c s0 This is fairly hard to demonstrate in a manner that makes this construction look useful! This demonstrates the basic operation: > e9 = runSM 0 (do x <- readSM -- should be 0 > updateSM (+1) > y <- readSM -- now a 1 > return (x,y)) Most of the SM functions are present in the next example in slightly altered forms. > type Resource = Integer > data R a = R (Resource -> (Resource, Either a (R a))) > instance Monad R where > R c1 >>= fc2 = R (\r -> case c1 r of > (r', Left v) -> let R c2 = fc2 v in > c2 r' > (r', Right pc1) -> (r', Right (pc1 >>= fc2))) > return v = R (\r -> (r, (Left v))) > step :: a -> R a > step v = c where > c = R (\r -> if r /= 0 then (r-1, Left v) > else (r, Right c)) > run :: Resource -> R a -> Maybe a > run s (R p) = case (p s) of > (_, Left v) -> Just v > _ -> Nothing > (|||) :: R a -> R a -> R a > c1 ||| c2 = oneStep c1 (\c1' -> c2 ||| c1') > where > oneStep :: R a -> (R a -> R a) -> R a > oneStep (R c1) f = > R (\r -> case c1 1 of > (r', Left v) -> (r+r'-1, Left v) > (r', Right c1') -> -- r' must be 0 > let R next = f c1' in > next (r+r'-1)) > lift1 :: (a -> b) -> (R a -> R b) > lift1 f = \ra1 -> do a1 <- ra1 > step (f a1) > lift2 :: (a -> b -> c) -> (R a -> R b -> R c) > lift2 f = \ra1 ra2 -> do a1 <- ra1 > a2 <- ra2 > step (f a1 a2) > (==*) :: Ord a => R a -> R a -> R Bool > (==*) = lift2 (==) These null instances are needed to allow the definition of Num (R a). > instance Show (R a) > instance Eq (R a) > instance Num a => Num (R a) where > (+) = lift2 (+) > (-) = lift2 (-) > negate = lift1 negate > (*) = lift2 (*) > abs = lift1 abs > fromInteger = return . fromInteger > ifR :: R Bool -> R a -> R a -> R a > ifR tst thn els = do t <- tst > if t then thn else els > inc :: R Integer -> R Integer > inc x = x + 1 > fact :: R Integer -> R Integer > fact x = ifR (x ==* 0) 1 (x * fact (x-1)) > e10 = run 0 (inc 1) -- won't complete > e11 = run 10 (inc 1) -- will complete > e12 = run 10 (fact 2) > e13 = run 10 (fact 20) > e14 = run 100 (fact (-1) ||| (fact 3)) We can dress this up a little with a nicer "run" function. This one adds a little more information: > run' :: Show a => Integer -> R a -> IO () > run' maxSteps (R p) = case (p maxSteps) of > (r, Left v) -> putStrLn ("Computed " ++ > show v ++ " in " ++ > show (maxSteps-r) ++ > " steps") > _ -> putStrLn ("Non termination.") > e15 = run' 100 (fact 3 ||| fact 4) > e16 = run' 100 (fact (-1) ||| fact 4) > e17 = run' 100 (fact 4) Continued in part19.lhs haskell-98-tutorial-sources/code/part19.lhs0100644000106400000620000000756606774446522017202 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 19 Covers Sections 10.1, 10.2, 10.3 > module Part19() where > import Complex Section: 10 Numbers Section: 10.1 Numeric Class Structure Section: 10.2 Constructed Numbers Here's a brief summary of Haskell numeric classes. Class Num Most general numeric class. Has addition, subtraction, multiplication. Integers can be coerced to any instance of Num with fromInteger. All integer constants are in this class. Instances: Int, Integer, Float, Double, Ratio a, Complex a Class Real This class contains ordered numbers which can be converted to rationals. Instances: Int, Integer, Float, Double, Ratio a Class Integral This class deals with integer division. All values in Integral can be mapped onto Integer. Instances: Int, Integer Class Fractional These are numbers which can be divided. Any rational number can be converted to a fractional. Floating point constants are in this class: 1.2 would be 12/10. Instances: Float, Double, Ratio a Class Floating This class contains all the standard floating point functions such as sqrt and sin. Instances: Float, Double, Complex a Class RealFrac These values can be rounded to integers and approximated by rationals. Instances: Float, Double, Ratio a Class RealFloat These are floating point numbers constructed from a fixed precision mantissa and exponent. Instances: Float, Double There are only a few sensible combinations of the constructed numerics with built-in types: Ratio Integer (same as Rational): arbitrary precision rationals Ratio Int: limited precision rationals Complex Float: complex numbers with standard precision components Complex Double: complex numbers with double precision components The following function works for arbitrary numerics: > fact :: (Num a) => a -> a > fact 0 = 1 > fact n = n*(fact (n-1)) Note the behavior when applied to different types of numbers: > e1 :: Int > e1 = fact 6 > e2 :: Int > e2 = fact 20 -- Hugs may not handle overflow gracefully! > e3 :: Integer > e3 = fact 20 > e4 :: Rational > e4 = fact 6 > e5 :: Float > e5 = fact 6 > e6 :: Complex Float > e6 = fact 6 Be careful: values like `fact 1.5' will loop. As a practical matter, Int operations are usually faster than Integer operations. Also, overloaded functions can be much slower than non- overloaded functions. Giving a function like fact a precise typing: fact :: Int -> Int may yield much faster code. In general, numeric expressions work as expected. Literals are a little tricky - they are coerced to the appropriate value. A constant like 1 can be used as ANY numeric type. > e7 :: Float > e7 = sqrt 2 > e8 :: Rational > e8 = ((4%5) * (1%2)) / (3%4) > e9 :: Rational > e9 = 2.2 * (3%11) - 1 > e10 :: Complex Float > e10 = (2 * (3:+3)) / ((1.1:+2.0) - 1) > e11 :: Complex Float > e11 = sqrt (-1) > e12 :: Integer > e12 = numerator (4%2) > e13 :: Complex Float > e13 = conjugate (4:+5.2) A function using pattern matching on complex numbers: > mag :: (RealFloat a) => Complex a -> a > mag (a:+b) = sqrt (a^2 + b^2) > e14 :: Float > e14 = mag (1:+1) Section: 10.3 Numeric Coercions and Overloaded Literals The Haskell type system does NOT implicitly coerce values between the different numeric types! Although overloaded constants are coerced when the overloading is resolved, no implicit coercion goes on when values of different types are mixed. For example: > f :: Float > f = 1.1 > i1 :: Int > i1 = 1 > i2 :: Integer > i2 = 2 All of these expressions would result in a type error (try them!): > -- g = i1 + f > -- h = i1 + i2 > -- i3 :: Int > -- i3 = i2 Appropriate coercions must be introduced by the user to allow the mixing of types in arithmetic expressions. > e15 :: Float > e15 = f + fromIntegral i1 > e16 :: Integer > e16 = fromIntegral i1 + i2 > e17 :: Int > e17 = i1 + fromInteger i2 -- fromIntegral would have worked too. Continued in part20.lhs haskell-98-tutorial-sources/code/part20.lhs0100644000106400000620000000402206774446522017152 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 20 Covers Section 10.4 > module Part20() where > import Complex Section: 10.4 Default Numeric Types Ambiguous contexts arise frequently in numeric expressions. When an expression which produces a value with a general type, such as `1' (same as `fromInteger 1'; the type is (Num a) => a), with another expression which `consumes' the type, such as `show' or `toInteger', ambiguity arises. This ambiguity can be resolved using expression type signatures, but this gets tedious fast! Assigning a type to the top level of an ambiguous expression does not help: the ambiguity does not propagate to the top level. > e1 :: String -- This type does not influence the type of the argument to show > e1 = show 1 -- Does this mean to show an Int or a Float or ... > e2 :: String > e2 = show (1 :: Float) > e3 :: String > e3 = show (1 :: Complex Float) The reason the first example works is that ambiguous numeric types are resolved using defaults. The defaults in effect here are Int and Double. Since Int `fits' in the expression for e1, Int is used. When Int is not valid (due to other context constraints), Double will be tried. This function defaults the type of the 2's to be Int > rms :: (Floating a) => a -> a -> a > rms x y = sqrt ((x^2 + y^2) * 0.5) One of the reasons for adding type signatures throughout these examples is to avoid unexpected defaulting. Many of the top level signatures are required to avoid ambiguity. Notice that defaulting applies only to numeric classes. The > -- show (read "xyz") -- Try this if you want! example uses only class Show so no defaulting occurs. Ambiguity also arises with polymorphic types. As discussed previously, expressions like [] have a similar problem. > e4 = [] -- Won't print since [] has type [a] and `a' is not known. Note the difference: even though the lists have no components, the type of component makes a difference in printing. > e5 = ([] :: [Int]) > e6 = ([] :: [Char]) Continued in part21.lhs haskell-98-tutorial-sources/code/part21.lhs0100644000106400000620000000114106774446522017152 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 21 Covers Section 11 Section 11 > module Part21() where Since each of these files is a separate module we need to place Tree in it's own module. See Tree.lhs > import Tree ( Tree(Leaf, Branch), fringe) > e1 :: [Int] > e1 = fringe (Branch (Leaf 1) (Leaf 2)) You could also just `import Tree' and get everything from Tree without explicitly naming the entities you need. This interactive Haskell environment can evaluate expressions in any module. You can do :m Tree to get to that module for interactive evaluation. Continued in Part22.lhs haskell-98-tutorial-sources/code/Tree.lhs0100644000106400000620000000041206774446522016740 0ustar jcpftp> module Tree ( Tree(Leaf,Branch), fringe ) where Tree(..) would work also > data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show > fringe :: Tree a -> [a] > fringe (Leaf x) = [x] > fringe (Branch left right) = fringe left ++ fringe right haskell-98-tutorial-sources/code/part22.lhs0100644000106400000620000000056706774446522017166 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 22 Covers Section 11.1 Section: 11.1 Qualified Names > module Part22() where > import Tree ( Tree(Leaf,Branch), fringe ) > import qualified Fringe ( fringe ) See Fringe.lhs > e1 = do print (fringe (Branch (Leaf 1) (Leaf 2))) > print (Fringe.fringe (Branch (Leaf 1) (Leaf 2))) Continued in part23.lhs haskell-98-tutorial-sources/code/Fringe.lhs0100644000106400000620000000025306774446522017256 0ustar jcpftp > module Fringe where > import Tree ( Tree(..)) > fringe :: Tree a -> [a] -- A different definition of fringe > fringe (Leaf x) = [x] > fringe (Branch x y) = fringe x haskell-98-tutorial-sources/code/part24.lhs0100644000106400000620000000332506774446522017163 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 24 Covers Sections 12, 12.1, 12.2, 12.3 Section: 12 Typing Pitfalls Section: 12.1 Let-Bound Polymorphism > module Part24() where > -- f g = (g 'a',g []) -- This won't typecheck. Section: 12.2 Overloaded Numerals Overloaded numerics were covered previously - here is one more example. sum is a prelude function which sums the elements of a list. > average :: (Fractional a) => [a] -> a > average xs = sum xs / fromIntegral (length xs) > e1 :: Float -- Note that e1 would default to Double instead of Integer - > -- this is due to the Fractional context. > e1 = average [1,2,3] Section: 12.3 The Monomorphism Restriction The monomorphism restriction is usually encountered when functions are defined without parameters. If you remove the signature for sum' the monomorphism restriction will apply. Hugs (at present) incorrectly defaults the type of sum' to Integer -> Integer without the type signature. If either of sumInt or sumFloat are present, these would determine the overloading. If both are present and sum' has no signature there is an error. > sum' :: (Num a) => [a] -> a > sum' = foldl (+) 0 -- foldl reduces a list with a binary function > -- 0 is the initial value. > sumInt :: Int > sumInt = sum' [1,2,3] > sumFloat :: Float > sumFloat = sum' [1,2,3] If you use overloaded constants you also may encounter monomorphism: > x :: Num a => a > x = 1 -- The type of x is Num a => a > y :: Int > y = x -- Uses x as an Int > z :: Integer > z = x -- Uses x as an Integer. A monomorphism will occur of the > -- signature for x is removed. Continued in part25.lhs haskell-98-tutorial-sources/code/part23.lhs0100644000106400000620000000102106774446522017151 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 23 Covers Sections 11.2, 11.3 11.2 Abstract Data Types > module Part23() where > import TreeADT See TreeADT.lhs Since the constructors for type Tree are hidden, pattern matching cannot be used. > fringe :: Tree a -> [a] > fringe x = if isLeaf x then [cell x] > else fringe (left x) ++ fringe (right x) > e1 :: [Int] > e1 = fringe (branch (branch (leaf 3) (leaf 2)) (leaf 1)) 11.3 More Features No examples (yet). Continued in part24.lhs haskell-98-tutorial-sources/code/TreeADT.lhs0100644000106400000620000000066506774446522017303 0ustar jcpftpSince TreeADT does not import Tree it can use the name Tree without any conflict. Each module has its own separate namespace. > module TreeADT (Tree, leaf, branch, cell, left, > right, isLeaf) where > data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show > leaf = Leaf > branch = Branch > cell (Leaf a) = a > left (Branch l r) = l > right (Branch l r) = r > isLeaf (Leaf _) = True > isLeaf _ = False haskell-98-tutorial-sources/code/part25.lhs0100644000106400000620000001527406774446522017172 0ustar jcpftpGentle Introduction to Haskell 98, Online Supplement Part 25 Covers Sections 13, 13.1, 13.2, 13.3, 13.4, 13.5 > module Part25() where > import Array Section: 13 Arrays Section: 13.1 Index Types Arrays are built on the class Ix. Here are some quick examples of Ix: > e1 :: [Int] > e1 = range (0,4) > e2 :: Int > e2 = index (0,4) 2 > low,high :: (Int,Int) > low = (1,1) > high = (3,4) > e3 = range (low,high) > e4 = index (low,high) (3,2) > e5 = inRange (low,high) (4,3) Section: 13.2 Array Creation > squares :: Array Int Int > squares = array (1,100) [(i,i*i) | i <- [1..100]] We can also parameterize this a little: > squares' :: Int -> Array Int Int > squares' n = array (1,n) [(i,i*i) | i <- [1..n]] > e6 :: Int > e6 = squares!6 > e7 :: (Int,Int) > e7 = bounds squares > e8 :: Array Int Int > e8 = squares' 10 Here is a function which corresponds to `take' for lists. It takes an arbitrary slice out of an array. > atake :: (Ix a) => Array a b -> (a,a) -> Array a b > atake a (l,u) | inRange (bounds a) l && inRange (bounds a) u = > array (l,u) [(i,a!i) | i <- range (l,u)] > | otherwise = error "Subarray out of range" > e9 = atake squares (4,8) > mkArray :: Ix a => (a -> b) -> (a,a) -> Array a b > mkArray f bnds = array bnds [(i,f i) | i <- range bnds] > e10 :: Array Int Int > e10 = mkArray (\i -> i*i) (1,10) > fibs :: Int -> Array Int Int > fibs n = a where > a = array (0,n) ([(0,1), (1,1)] ++ > [(i,a!(i-1) + a!(i-2)) | i <- [2..n]]) > e11 = atake (fibs 50) (3,10) > wavefront :: Int -> Array (Int,Int) Int > wavefront n = a where > a = array ((1,1),(n,n)) > ([((1,j),1) | j <- [1..n]] ++ > [((i,1),1) | i <- [2..n]] ++ > [((i,j),a!(i,j-1) + a!(i-1,j-1) + a!(i-1,j)) > | i <- [2..n], j <- [2..n]]) > wave = wavefront 20 > e12 = atake wave ((1,1),(3,3)) > e13 = atake wave ((3,3),(5,5)) Here are some errors in array operations: > e14 :: Int > e14 = wave ! (0,0) -- Out of bounds > arr1 :: Array Int Int > arr1 = array (1,10) [(1,1)] -- No value provided for 2..10 > e15,e16 :: Int > e15 = arr1 ! 1 -- works OK > e16 = arr1 ! 2 -- undefined by array Section: 13.3 Accumulation > hist :: (Ix a, Integral b) => (a,a) -> [a] -> Array a b > hist bnds is = accumArray (+) 0 bnds [(i,1) | i <- is, inRange bnds i] > e17 :: Array Char Int > e17 = hist ('a','z') "This counts the frequencies of each lowercase letter" > decades :: (RealFrac a) => a -> a -> [a] -> Array Int Int > decades a b = hist (0,9) . map decade > where > decade x = floor ((x-a) * s) > s = 10 / (b - a) > test1 :: [Float] > test1 = map sin [0..100] -- take the sine of the 0 - 100 > e18 = decades 0 1 test1 Section: 13.4 Incremental Updates > swapRows :: (Ix a, Ix b, Enum b) => a -> a -> Array (a,b) c -> Array (a,b) c > swapRows i i' a = a // ([((i,j),a!(i',j)) | j <- [jLo..jHi]] ++ > [((i',j),a!(i,j)) | j <- [jLo..jHi]]) > where ((iLo,jLo),(iHi,jHi)) = bounds a > arr2 :: Array (Int,Int) (Int,Int) > arr2 = array ((1,1),(5,5)) [((i,j),(i,j)) | (i,j) <- range ((1,1),(5,5))] > e19 = swapRows 2 3 arr2 Printing the arrays in more readable form makes the results easier to view. This is a printer for 2d arrays; width is # of columns per element > aprint :: (Show b) => Array (Int, Int) b -> Int -> ShowS > aprint a width = shows (bounds a) . showChar '\n' . showRows lx ly where > showRows r c | r > ux = showChar '\n' > showRows r c | c > uy = showChar '\n' . showRows (r+1) ly > showRows r c = showElt (a!(r,c)) . showRows r (c+1) > showElt e = showString (take width (show e ++ repeat ' ')) . showChar ' ' > ((lx,ly),(ux,uy)) = bounds a > showArray :: (Show b) => Array (Int, Int) b -> Int -> IO () > showArray a w = putStrLn (aprint a w "") > e20 = showArray e19 6 > swapRows' :: (Ix a, Ix b, Enum b) => a -> a -> Array (a,b) c -> Array (a,b) c > swapRows' i i' a = a // [assoc | j <- [jLo..jHi], > assoc <- [((i,j),a!(i',j)), > ((i',j),a!(i,j))]] > where ((iLo,jLo),(iHi,jHi)) = bounds a > e21 = showArray (swapRows' 1 5 arr2) 6 Section: 13.5 An example: Matrix Multiplication > matMult :: (Ix a, Ix b, Ix c, Num d) => > Array (a,b) d -> Array (b,c) d -> Array (a,c) d > matMult x y = > array resultBounds > [((i,j), sum [x!(i,k) * y!(k,j) | k <- range (lj,uj)]) > | i <- range (li,ui), > j <- range (lj',uj')] > where > ((li,lj),(ui,uj)) = bounds x > ((li',lj'),(ui',uj')) = bounds y > resultBounds > | (lj,uj)==(li',ui') = ((li,lj'),(ui,uj')) > | otherwise = error "matMult: incompatible bounds" > mat1,mat2,mat3,mat4 :: Array (Int,Int) Int > mat1 = array ((0,0),(1,1)) [((0,0),1), ((0,1),0), ((1,0),0), ((1,1),1)] > mat2 = array ((0,0),(1,1)) [((0,0),1), ((0,1),1), ((1,0),1), ((1,1),1)] > mat3 = array ((0,0),(1,1)) [((0,0),1), ((0,1),2), ((1,0),3), ((1,1),4)] > mat4 = array ((0,0),(1,2)) [((0,0),1), ((0,1),2), ((0,2),3), > ((1,0),4), ((1,1),5), ((1,2),6)] > e22 = showArray (matMult mat1 mat2) 4 > e23 = showArray (matMult mat2 mat3) 4 > e24 = showArray (matMult mat1 mat4) 4 > e25 = showArray (matMult mat4 mat1) 4 > matMult' :: (Ix a, Ix b, Ix c, Num d) => > Array (a,b) d -> Array (b,c) d -> Array (a,c) d > matMult' x y = > accumArray (+) 0 ((li,lj'),(ui,uj')) > [((i,j), x!(i,k) * y!(k,j)) > | i <- range (li,ui), > j <- range (lj',uj'), > k <- range (lj,uj)] > where > ((li,lj),(ui,uj)) = bounds x > ((li',lj'),(ui',uj')) = bounds y > resultBounds > | (lj,uj)==(li',ui') = ((li,lj'),(ui,uj')) > | otherwise = error "matMult: incompatible bounds" > e26 = showArray (matMult mat1 mat2) 4 > e27 = showArray (matMult mat2 mat3) 4 > genMatMul :: (Ix a, Ix b, Ix c) => > ([f] -> g) -> (d -> e -> f) -> > Array (a,b) d -> Array (b,c) e -> Array (a,c) g > genMatMul f g x y = > array ((li,lj'),(ui,uj')) > [((i,j), f [(x!(i,k)) `g` (y!(k,j)) | k <- range (lj,uj)]) > | i <- range (li,ui), > j <- range (lj',uj')] > where > ((li,lj),(ui,uj)) = bounds x > ((li',lj'),(ui',uj')) = bounds y > resultBounds > | (lj,uj)==(li',ui') = ((li,lj'),(ui,uj')) > | otherwise = error "matMult: incompatible bounds" > e28 = showArray (genMatMul maximum (-) mat2 mat1) 4 > e29 = showArray (genMatMul and (==) mat1 mat2) 6 > e30 = showArray (genMatMul and (==) mat1 mat1) 6 This is the end of the online supplement haskell-98-tutorial-sources/haskell-tutorial.tex0100644000106400000620000000415507116002507020413 0ustar jcpftp \documentclass[twoside,11pt]{article} \textheight=8.5in \textwidth=6.5in \topmargin=-.3in \oddsidemargin=0in \evensidemargin=0in \parskip=6pt plus2pt minus2pt \pagestyle{headings} \input{report-refs} \usepackage{epsf} % \renewcommand{\thepage}{T-\arabic{page}} \newcommand{\folks}[1]{\begin{quote}\sf#1\end{quote}} \newcommand{\bc}{\begin{center}} \newcommand{\ec}{\end{center}} \newcommand{\be}{\begin{enumerate}} \newcommand{\ee}{\end{enumerate}} \newcommand{\ba}{\begin{array}} \newcommand{\ea}{\end{array}} \newcommand{\x}{\times} \newcommand{\lam}{\lambda} \newcommand{\la}{\leftarrow} \newcommand{\ra}{\rightarrow} \newcommand{\red}{\Rightarrow} \newcommand{\see}[1]{\S\ref{#1}} \newcommand{\syn}[1]{[#1]} \newcommand{\bprog}{% \par\noindent\begin{tabular}{@{\hspace*{17pt}}l@{}}} \newcommand{\eprog}{% \end{tabular}\\[\parskip]} \newcommand{\eprogNoSkip}{% \end{tabular}} \newcommand{\anchor}[2]{#2} \begin{document} \title{A Gentle Introduction to Haskell 98} \author{Paul Hudak\\ Yale University\\ Department of Computer Science \and John Peterson\\ Yale University\\ Department of Computer Science \and Joseph H. Fasel\\ University of California\\ Los Alamos National Laboratory} \date{October, 1999} \maketitle Copyright \copyright\ 1999 Paul Hudak, John Peterson and Joseph Fasel Permission is hereby granted, free of charge, to any person obtaining a copy of ``A Gentle Introduction to Haskell'' (the Text), to deal in the Text without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Text, and to permit persons to whom the Text is furnished to do so, subject to the following condition: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Text. \input{intro} \input{goodies} \input{functions} \input{patterns} \input{classes} \input{moretypes} \input{io} \input{stdclasses} \input{monads} \input{numbers} \input{modules} \input{pitfalls} \input{arrays} \input{end} \bibliographystyle{plain} \bibliography{tut} \end{document} haskell-98-tutorial-sources/io.tex0100644000106400000620000005032407116002315015532 0ustar jcpftp%**A Gentle Introduction to Haskell: IO %**~header \section{Input/Output} \label{tut-io} The I/O system in Haskell is purely functional, yet has all of the expressive power found in conventional programming languages. In imperative languages, programs proceed via \mbox{$\it actions$} which examine and modify the current state of the world. Typical actions include reading and setting global variables, writing files, reading input, and opening windows. Such actions are also a part of Haskell but are cleanly separated from the purely functional core of the language. Haskell's I/O system is built around a somewhat daunting mathematical foundation: the \mbox{$\it monad$}. However, understanding of the underlying monad theory is not necessary to program using the I/O system. Rather, monads are a conceptual structure into which I/O happens to fit. It is no more necessary to understand monad theory to perform Haskell I/O than it is to understand group theory to do simple arithmetic. A detailed explanation of monads is found in Section \ref{tut-monads}. The monadic operators that the I/O system is built upon are also used for other purposes; we will look more deeply into monads later. For now, we will avoid the term monad and concentrate on the use of the I/O system. It's best to think of the I/O monad as simply an abstract data type. Actions are defined rather than invoked within the expression language of Haskell. Evaluating the definition of an action doesn't actually cause the action to happen. Rather, the invocation of actions takes place outside of the expression evaluation we have considered up to this point. Actions are either atomic, as defined in system primitives, or are a sequential composition of other actions. The I/O monad contains primitives which build composite actions, a process similar to joining statements in sequential order using `\mbox{\tt ;}' in other languages. Thus the monad serves as the glue which binds together the actions in a program. \subsection{Basic I/O Operations} Every I/O action returns a value. In the type system, the return value is `tagged' with \mbox{\tt IO} type, distinguishing actions from other values. For example, the type of the function \mbox{\tt getChar} is: \bprog \mbox{\tt getChar\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ \ \ IO\ Char} \eprog The \mbox{\tt IO\ Char} indicates that \mbox{\tt getChar}, when invoked, performs some action which returns a character. Actions which return no interesting values use the unit type, \mbox{\tt ()}. For example, the \mbox{\tt putChar} function: \bprog \mbox{\tt putChar\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ \ \ \ Char\ ->\ IO\ ()} \eprog takes a character as an argument but returns nothing useful. The unit type is similar to \mbox{\tt void} in other languages. Actions are sequenced using an operator that has a rather cryptic name: \mbox{\tt >>=} (or `bind'). Instead of using this operator directly, we choose some syntactic sugar, the \mbox{\tt do} notation, to hide these sequencing operators under a syntax resembling more conventional languages. The \mbox{\tt do} notation can be trivially expanded to \mbox{\tt >>=}, as described in \see{do-expressions}. The keyword \mbox{\tt do} introduces a sequence of statements which are executed in order. A statement is either an action, a pattern bound to the result of an action using \mbox{\tt <-}, or a set of local definitions introduced using \mbox{\tt let}. The \mbox{\tt do} notation uses layout in the same manner as \mbox{\tt let} or \mbox{\tt where} so we can omit braces and semicolons with proper indentation. Here is a simple program to read and then print a character: \bprog \mbox{\tt main\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ IO\ ()}\\ \mbox{\tt main\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ do\ c\ <-\ getChar}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ putChar\ c} \eprog The use of the name \mbox{\tt main} is important: \mbox{\tt main} is defined to be the entry point of a Haskell program (similar to the \mbox{\tt main} function in C), and must have an \mbox{\tt IO} type, usually \mbox{\tt IO\ ()}. (The name \mbox{\tt main} is special only in the module \mbox{\tt Main}; we will have more to say about modules later.) This program performs two actions in sequence: first it reads in a character, binding the result to the variable c, and then prints the character. Unlike a \mbox{\tt let} expression where variables are scoped over all definitions, the variables defined by \mbox{\tt <-} are only in scope in the following statements. There is still one missing piece. We can invoke actions and examine their results using \mbox{\tt do}, but how do we return a value from a sequence of actions? For example, consider the \mbox{\tt ready} function that reads a character and returns \mbox{\tt True} if the character was a `y': \bprog \mbox{\tt ready\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ IO\ Bool}\\ \mbox{\tt ready\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ do\ c\ <-\ getChar}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ c\ ==\ 'y'\ \ --\ Bad!!!} \eprog This doesn't work because the second statement in the `do' is just a boolean value, not an action. We need to take this boolean and create an action that does nothing but return the boolean as its result. The \mbox{\tt return} function does just that: \bprog \mbox{\tt return\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ \ \ a\ ->\ IO\ a} \eprog The \mbox{\tt return} function completes the set of sequencing primitives. The last line of \mbox{\tt ready} should read \mbox{\tt return\ (c\ ==\ 'y')}. We are now ready to look at more complicated I/O functions. First, the function \mbox{\tt getLine}: \bprog \mbox{\tt getLine\ \ \ \ \ ::\ IO\ String}\\ \mbox{\tt getLine\ \ \ \ \ =\ \ do\ c\ <-\ getChar}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ c\ ==\ '{\char'134}n'}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ then\ return\ ""}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ do\ l\ <-\ getLine}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ (c:l)} \eprog Note the second \mbox{\tt do} in the else clause. Each \mbox{\tt do} introduces a single chain of statements. Any intervening construct, such as the \mbox{\tt if}, must use a new \mbox{\tt do} to initiate further sequences of actions. The \mbox{\tt return} function admits an ordinary value such as a boolean to the realm of I/O actions. What about the other direction? Can we invoke some I/O actions within an ordinary expression? For example, how can we say \mbox{\tt x\ +\ print\ y} in an expression so that \mbox{\tt y} is printed out as the expression evaluates? The answer is that we can't! It is \mbox{$\it not$} possible to sneak into the imperative universe while in the midst of purely functional code. Any value `infected' by the imperative world must be tagged as such. A function such as \bprog \mbox{\tt f\ \ \ \ ::\ \ Int\ ->\ Int\ ->\ Int} \eprog absolutely cannot do any I/O since \mbox{\tt IO} does not appear in the returned type. This fact is often quite distressing to programmers used to placing print statements liberally throughout their code during debugging. There are, in fact, some unsafe functions available to get around this problem but these are better left to advanced programmers. Debugging packages (like \mbox{\tt Trace}) often make liberal use of these `forbidden functions' in an entirely safe manner. \subsection{Programming With Actions} I/O actions are ordinary Haskell values: they may be passed to functions, placed in structures, and used as any other Haskell value. Consider this list of actions: \bprog \mbox{\tt todoList\ ::\ [IO\ ()]}\\ \mbox{\tt }\\[-8pt] \mbox{\tt todoList\ =\ [putChar\ 'a',}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ do\ putChar\ 'b'}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ putChar\ 'c',}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ do\ c\ <-\ getChar}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ putChar\ c]} \eprog This list doesn't actually invoke any actions---it simply holds them. To join these actions into a single action, a function such as \mbox{\tt sequence{\char'137}} is needed: \bprog \mbox{\tt sequence{\char'137}\ \ \ \ \ \ \ \ ::\ [IO\ ()]\ ->\ IO\ ()}\\ \mbox{\tt sequence{\char'137}\ []\ \ \ \ \ =\ \ return\ ()}\\ \mbox{\tt sequence{\char'137}\ (a:as)\ =\ \ do\ a}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ sequence\ as} \eprog This can be simplified by noting that \mbox{\tt do\ x;y} is expanded to \mbox{\tt x\ >>\ y} (see Section \ref{tut-monadic-classes}). This pattern of recursion is captured by the \mbox{\tt foldr} function (see the Prelude for a definition of \mbox{\tt foldr}); a better definition of \mbox{\tt sequence{\char'137}} is: \bprog \mbox{\tt sequence{\char'137}\ \ \ \ \ \ \ \ ::\ [IO\ ()]\ ->\ IO\ ()}\\ \mbox{\tt sequence{\char'137}\ \ \ \ \ \ \ \ =\ \ foldr\ (>>)\ (return\ ())} \eprog The \mbox{\tt do} notation is a useful tool but in this case the underlying monadic operator, \mbox{\tt >>}, is more appropriate. An understanding of the operators upon which \mbox{\tt do} is built is quite useful to the Haskell programmer. The \mbox{\tt sequence{\char'137}} function can be used to construct \mbox{\tt putStr} from \mbox{\tt putChar}: \bprog \mbox{\tt putStr\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ String\ ->\ IO\ ()}\\ \mbox{\tt putStr\ s\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ sequence{\char'137}\ (map\ putChar\ s)} \eprog One of the differences between Haskell and conventional imperative programming can be seen in \mbox{\tt putStr}. In an imperative language, mapping an imperative version of \mbox{\tt putChar} over the string would be sufficient to print it. In Haskell, however, the \mbox{\tt map} function does not perform any action. Instead it creates a list of actions, one for each character in the string. The folding operation in \mbox{\tt sequence{\char'137}} uses the \mbox{\tt >>} function to combine all of the individual actions into a single action. The \mbox{\tt return\ ()} used here is quite necessary -- \mbox{\tt foldr} needs a null action at the end of the chain of actions it creates (especially if there are no characters in the string!). The Prelude and the libraries contains many functions which are useful for sequencing I/O actions. These are usually generalized to arbitrary monads; any function with a context including \mbox{\tt Monad\ m\ =>} works with the \mbox{\tt IO} type. \subsection{Exception Handling} So far, we have avoided the issue of exceptions during I/O operations. What would happen if \mbox{\tt getChar} encounters an end of file?\footnote{We use the term \mbox{$\it error$} for \mbox{$\it \bot$}: a condition which cannot be recovered from such as non-termination or pattern match failure. Exceptions, on the other hand, can be caught and handled within the I/O monad.} To deal with exceptional conditions such as `file not found' within the I/O monad, a handling mechanism is used, similar in functionality to the one in standard ML. No special syntax or semantics are used; exception handling is part of the definition of the I/O sequencing operations. Errors are encoded using a special data type, \mbox{\tt IOError}. This type represents all possible exceptions that may occur within the I/O monad. This is an abstract type: no constructors for \mbox{\tt IOError} are available to the user. Predicates allow \mbox{\tt IOError} values to be queried. For example, the function \bprog \mbox{\tt isEOFError\ \ \ \ \ \ \ ::\ IOError\ ->\ Bool} \eprog determines whether an error was caused by an end-of-file condition. By making \mbox{\tt IOError} abstract, new sorts of errors may be added to the system without a noticeable change to the data type. The function \mbox{\tt isEOFError} is defined in a separate library, \mbox{\tt IO}, and must be explicitly imported into a program. An {\em exception handler} has type \mbox{\tt IOError\ ->\ IO\ a}. The \mbox{\tt catch} function associates an exception handler with an action or set of actions: \bprog \mbox{\tt catch\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ IO\ a\ ->\ (IOError\ ->\ IO\ a)\ ->\ IO\ a} \eprog The arguments to \mbox{\tt catch} are an action and a handler. If the action succeeds, its result is returned without invoking the handler. If an error occurs, it is passed to the handler as a value of type \mbox{\tt IOError} and the action associated with the handler is then invoked. For example, this version of \mbox{\tt getChar} returns a newline when an error is encountered: \bprog \mbox{\tt getChar'\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ IO\ Char}\\ \mbox{\tt getChar'\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ getChar\ `catch`\ ({\char'134}e\ ->\ return\ '{\char'134}n')} \eprog This is rather crude since it treats all errors in the same manner. If only end-of-file is to be recognized, the error value must be queried: \bprog \mbox{\tt getChar'\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ IO\ Char}\\ \mbox{\tt getChar'\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ getChar\ `catch`\ eofHandler\ where}\\ \mbox{\tt \ \ \ \ eofHandler\ e\ =\ if\ isEofError\ e\ then\ return\ '{\char'134}n'\ else\ ioError\ e} \eprog The \mbox{\tt ioError} function used here throws an exception on to the next exception handler. The type of \mbox{\tt ioError} is \bprog \mbox{\tt ioError\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ IOError\ ->\ IO\ a} \eprog It is similar to \mbox{\tt return} except that it transfers control to the exception handler instead of proceeding to the next I/O action. Nested calls to \mbox{\tt catch} are permitted, and produce nested exception handlers. Using \mbox{\tt getChar'}, we can redefine \mbox{\tt getLine} to demonstrate the use of nested handlers: \bprog \mbox{\tt getLine'\ \ \ \ \ \ \ \ ::\ IO\ String}\\ \mbox{\tt getLine'\ \ \ \ \ \ \ \ =\ catch\ getLine''\ ({\char'134}err\ ->\ return\ ("Error:\ "\ ++\ show\ err))}\\ \mbox{\tt \ \ \ \ \ \ \ \ where}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ getLine''\ =\ do\ c\ <-\ getChar'}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ c\ ==\ '{\char'134}n'\ then\ return\ ""}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ do\ l\ <-\ getLine'}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ (c:l)} \eprog The nested error handlers allow \mbox{\tt getChar'} to catch end of file while any other error results in a string starting with \mbox{\tt "Error:\ "} from \mbox{\tt getLine'}. For convenience, Haskell provides a default exception handler at the topmost level of a program that prints out the exception and terminates the program. \subsection{Files, Channels, and Handles} Aside from the I/O monad and the exception handling mechanism it provides, I/O facilities in Haskell are for the most part quite similar to those in other languages. Many of these functions are in the \mbox{\tt IO} library instead of the Prelude and thus must be explicitly imported to be in scope (modules and importing are discussed in Section~\ref{tut-modules}). Also, many of these functions are discussed in the Library Report instead of the main report. Opening a file creates a \mbox{$\it handle$} (of type \mbox{\tt Handle}) for use in I/O transactions. Closing the handle closes the associated file: \bprog \mbox{\tt type\ FilePath\ \ \ \ \ \ \ \ \ =\ \ String\ \ --\ path\ names\ in\ the\ file\ system}\\ \mbox{\tt openFile\ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ FilePath\ ->\ IOMode\ ->\ IO\ Handle}\\ \mbox{\tt hClose\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Handle\ ->\ IO\ ()\ }\\ \mbox{\tt data\ IOMode\ \ \ \ \ \ \ \ \ \ \ =\ \ ReadMode\ |\ WriteMode\ |\ AppendMode\ |\ ReadWriteMode} \eprog Handles can also be associated with \mbox{$\it channels$}: communication ports not directly attached to files. A few channel handles are predefined, including \mbox{\tt stdin} (standard input), \mbox{\tt stdout} (standard output), and \mbox{\tt stderr} (standard error). Character level I/O operations include \mbox{\tt hGetChar} and \mbox{\tt hPutChar}, which take a handle as an argument. The \mbox{\tt getChar} function used previously can be defined as: \bprog \mbox{\tt getChar\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ hGetChar\ stdin} \eprog Haskell also allows the entire contents of a file or channel to be returned as a single string: \bprog \mbox{\tt getContents\ \ \ \ \ \ \ \ \ \ \ \ ::\ Handle\ ->\ IO\ String} \eprog Pragmatically, it may seem that \mbox{\tt getContents} must immediately read an entire file or channel, resulting in poor space and time performance under certain conditions. However, this is not the case. The key point is that \mbox{\tt getContents} returns a ``lazy'' (i.e. non-strict) list of characters (recall that strings are just lists of characters in Haskell), whose elements are read ``by demand'' just like any other list. An implementation can be expected to implement this demand-driven behavior by reading one character at a time from the file as they are required by the computation. In this example, a Haskell program copies one file to another: \bprog \mbox{\tt main\ =\ do\ fromHandle\ <-\ getAndOpenFile\ "Copy\ from:\ "\ ReadMode}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ toHandle\ \ \ <-\ getAndOpenFile\ "Copy\ to:\ "\ WriteMode\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ contents\ \ \ <-\ hGetContents\ fromHandle}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ hPutStr\ toHandle\ contents}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ hClose\ toHandle}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ putStr\ "Done."}\\ \mbox{\tt }\\[-8pt] \mbox{\tt getAndOpenFile\ \ \ \ \ \ \ \ \ \ ::\ String\ ->\ IOMode\ ->\ IO\ Handle}\\ \mbox{\tt }\\[-8pt] \mbox{\tt getAndOpenFile\ prompt\ mode\ =}\\ \mbox{\tt \ \ \ \ do\ putStr\ prompt}\\ \mbox{\tt \ \ \ \ \ \ \ name\ <-\ getLine}\\ \mbox{\tt \ \ \ \ \ \ \ catch\ (openFile\ name\ mode)}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ ({\char'134}{\char'137}\ ->\ do\ putStrLn\ ("Cannot\ open\ "++\ name\ ++\ "{\char'134}n")}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ getAndOpenFile\ prompt\ mode)}\\ \mbox{\tt }\\[-8pt] \mbox{\tt } \eprog By using the lazy \mbox{\tt getContents} function, the entire contents of the file need not be read into memory all at once. If \mbox{\tt hPutStr} chooses to buffer the output by writing the string in fixed sized blocks of characters, only one block of the input file needs to be in memory at once. The input file is closed implicitly when the last character has been read. \subsection{Haskell and Imperative Programming} As a final note, I/O programming raises an important issue: this style looks suspiciously like ordinary imperative programming. For example, the \mbox{\tt getLine} function: \bprog \mbox{\tt getLine\ \ \ \ \ \ \ \ \ =\ do\ c\ <-\ getChar}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ c\ ==\ '{\char'134}n'}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ then\ return\ ""}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ do\ l\ <-\ getLine}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ (c:l)} \eprog bears a striking similarity to imperative code (not in any real language) : \bprog \mbox{\tt }\\[-8pt] \mbox{\tt function\ getLine()\ {\char'173}}\\ \mbox{\tt \ \ c\ :=\ getChar();}\\ \mbox{\tt \ \ if\ c\ ==\ `{\char'134}n`\ then\ return\ ""}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ {\char'173}l\ :=\ getLine();}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ c:l{\char'175}{\char'175}} \eprog So, in the end, has Haskell simply re-invented the imperative wheel? In some sense, yes. The I/O monad constitutes a small imperative sub-language inside Haskell, and thus the I/O component of a program may appear similar to ordinary imperative code. But there is one important difference: There is no special semantics that the user needs to deal with. In particular, equational reasoning in Haskell is not compromised. The imperative feel of the monadic code in a program does not detract from the functional aspect of Haskell. An experienced functional programmer should be able to minimize the imperative component of the program, only using the I/O monad for a minimal amount of top-level sequencing. The monad cleanly separates the functional and imperative program components. In contrast, imperative languages with functional subsets do not generally have any well-defined barrier between the purely functional and imperative worlds. %**~footer haskell-98-tutorial-sources/intro.tex0100644000106400000620000000667007121451726016275 0ustar jcpftp%**A Gentle Introduction to Haskell: Introduction %**~sheader \section{Introduction} \label{tut-intro} Our purpose in writing this tutorial is not to teach programming, nor even to teach functional programming. Rather, it is intended to serve as a supplement to the Haskell Report \cite{haskell-98}, which is otherwise a rather dense technical exposition. Our goal is to provide a gentle introduction to Haskell for someone who has experience with at least one other language, preferably a functional language (even if only an ``almost-functional'' language such as ML or Scheme). If the reader wishes to learn more about the functional programming style, we highly recommend Bird's text {\em Introduction to Functional Programming} \cite{bird98} or Davie's {\em An Introduction to Functional Programming Systems Using Haskell} \cite{davie92}. For a useful survey of functional programming languages and techniques, including some of the language design principles used in Haskell, see \cite{huda89a}. The Haskell language has evolved significantly since its birth in 1987. This tutorial deals with \anchor{http://haskell.org/report} {Haskell 98}. Older versions of the language are now obsolete; Haskell users are encouraged to use Haskell 98. There are also many extensions to Haskell 98 that have been widely implemented. These are not yet a formal part of the Haskell language and are not covered in this tutorial. Our general strategy for introducing language features is this: motivate the idea, define some terms, give some examples, and then point to the Report for details. We suggest, however, that the reader completely ignore the details until the {\em Gentle Introduction} has been completely read. On the other hand, Haskell's Standard Prelude (in Appendix A of the Report and the standard libraries (found in the \anchor{http://haskell.org/library} Library Report~\cite{haskell-libs}) contain lots of useful examples of Haskell code; we encourage a thorough reading once this tutorial is completed. This will not only give the reader a feel for what real Haskell code looks like, but will also familiarize her with Haskell's standard set of predefined functions and types. Finally, the Haskell web site, \anchor{http://haskell.org}{{\tt http://haskell.org}}, has a wealth of information about the Haskell language and its implementations. \syn{We have also taken the course of not laying out a plethora of lexical syntax rules at the outset. Rather, we introduce them incrementally as our examples demand, and enclose them in brackets, as with this paragraph. This is in stark contrast to the organization of the Report, although the Report remains the authoritative source for details (references such as ``\S 2.1'' refer to sections in the Report).} Haskell is a {\em typeful} programming language:\footnote{Coined by Luca Cardelli.} types are pervasive, and the newcomer is best off becoming well aware of the full power and complexity of Haskell's type system from the outset. For those whose only experience is with relatively ``untypeful'' languages such as Perl, Tcl, or Scheme, this may be a difficult adjustment; for those familiar with Java, C, Modula, or even ML, the adjustment should be easier but still not insignificant, since Haskell's type system is different and somewhat richer than most. In any case, ``typeful programming'' is part of the Haskell programming experience, and cannot be avoided. % \maybeInclude{intro-extra} %**~sfooter haskell-98-tutorial-sources/goodies.tex0100644000106400000620000006365207116002314016563 0ustar jcpftp%**A Gentle Introduction to Haskell: Values and Types %**~header \section{Values, Types, and Other Goodies} \label{tut-values-etc} Because Haskell is a purely functional language, all computations are done via the evaluation of {\em expressions} (syntactic terms) to yield {\em values} (abstract entities that we regard as answers). Every value has an associated {\em type}. (Intuitively, we can think of types as sets of values.) Examples of expressions include atomic values such as the integer \mbox{\tt 5}, the character \mbox{\tt 'a'}, and the function \mbox{\tt {\char'134}x\ ->\ x+1}, as well as structured values such as the list \mbox{\tt [1,2,3]} and the pair \mbox{\tt ('b',4)}. Just as expressions denote values, type expressions are syntactic terms that denote type values (or just {\em types}). Examples of type expressions include the atomic types \mbox{\tt Integer} (infinite-precision integers), \mbox{\tt Char} (characters), \mbox{\tt Integer->Integer} (functions mapping \mbox{\tt Integer} to \mbox{\tt Integer}), as well as the structured types \mbox{\tt [Integer]} (homogeneous lists of integers) and \mbox{\tt (Char,Integer)} (character, integer pairs). All Haskell values are ``first-class''---they may be passed as arguments to functions, returned as results, placed in data structures, etc. Haskell types, on the other hand, are {\em not} first-class. Types in a sense describe values, and the association of a value with its type is called a {\em typing}. Using the examples of values and types above, we write typings as follows: \bprog \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 5\ \ ::\ Integer}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 'a'\ ::\ Char}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ inc\ ::\ Integer\ ->\ Integer}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [1,2,3]\ ::\ [Integer]}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ('b',4)\ ::\ (Char,Integer)} \eprog The ``\mbox{\tt ::}'' can be read ``has type.'' Functions in Haskell are normally defined by a series of {\em equations}. For example, the function \mbox{\tt inc} can be defined by the single equation: \bprog \mbox{\tt inc\ n\ \ \ \ \ \ \ \ \ \ =\ n+1} \eprog An equation is an example of a {\em declaration}. Another kind of declaration is a {\em type signature declaration} (\see{type-signatures}), with which we can declare an explicit typing for \mbox{\tt inc}: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ ::\ Integer\ ->\ Integer} \eprog We will have much more to say about function definitions in Section \ref{tut-functions}. For pedagogical purposes, when we wish to indicate that an expression $e_1$ evaluates, or ``reduces,'' to another expression or value $e_2$, we will write: \[ e_1\ \ \ \ \red\ \ \ \ e_2 \] For example, note that: \[ \mbox{\tt inc\ (inc\ 3)}\ \ \ \ \red\ \ \ \ \mbox{\tt 5} \] Haskell's static type system defines the formal relationship between types and values (\see{type-semantics}). The static type system ensures that Haskell programs are {\em type safe}; that is, that the programmer has not mismatched types in some way. For example, we cannot generally add together two characters, so the expression \mbox{\tt 'a'+'b'} is ill-typed. The main advantage of statically typed languages is well-known: All type errors are detected at compile-time. Not all errors are caught by the type system; an expression such as \mbox{\tt 1/0} is typable but its evaluation will result in an error at execution time. Still, the type system finds many program errors at compile time, aids the user in reasoning about programs, and also permits a compiler to generate more efficient code (for example, no run-time type tags or tests are required). The type system also ensures that user-supplied type signatures are correct. In fact, Haskell's type system is powerful enough to allow us to avoid writing any type signatures at all;\footnote{With a few exceptions to be described later.} we say that the type system {\em infers} the correct types for us. Nevertheless, judicious placement of type signatures such as that we gave for \mbox{\tt inc} is a good idea, since type signatures are a very effective form of documentation and help bring programming errors to light. \syn{The reader will note that we have capitalized identifiers that denote specific types, such as \mbox{\tt Integer} and \mbox{\tt Char}, but not identifiers that denote values, such as \mbox{\tt inc}. This is not just a convention: it is enforced by Haskell's lexical syntax. In fact, the case of the other characters matters, too: \mbox{\tt foo}, \mbox{\tt fOo}, and \mbox{\tt fOO} are all distinct identifiers.} \subsection{Polymorphic Types} \label{tut-polymorphism} Haskell also incorporates {\em polymorphic} types---types that are universally quantified in some way over all types. Polymorphic type expressions essentially describe families of types. For example, $(\forall$\mbox{\tt a}$)$\mbox{\tt [a]} is the family of types consisting of, for every type \mbox{\tt a}, the type of lists of \mbox{\tt a}. Lists of integers (e.g.~\mbox{\tt [1,2,3]}), lists of characters (\mbox{\tt ['a','b','c']}), even lists of lists of integers, etc., are all members of this family. (Note, however, that \mbox{\tt [2,'b']} is {\em not} a valid example, since there is no single type that contains both \mbox{\tt 2} and \mbox{\tt 'b'}.) \syn{Identifiers such as \mbox{\tt a} above are called {\em type variables}, and are uncapitalized to distinguish them from specific types such as \mbox{\tt Int}. Furthermore, since Haskell has only universally quantified types, there is no need to explicitly write out the symbol for universal quantification, and thus we simply write \mbox{\tt [a]} in the example above. In other words, all type variables are implicitly universally quantified.} Lists are a commonly used data structure in functional languages, and are a good vehicle for explaining the principles of polymorphism. The list \mbox{\tt [1,2,3]} in Haskell is actually shorthand for the list \mbox{\tt 1:(2:(3:[]))}, where \mbox{\tt []} is the empty list and \mbox{\tt :} is the infix operator that adds its first argument to the front of its second argument (a list).\footnote{\mbox{\tt :} and \mbox{\tt []} are like Lisp's \mbox{\tt cons} and \mbox{\tt nil}, respectively.} Since \mbox{\tt :} is right associative, we can also write this list as \mbox{\tt 1:2:3:[]}. As an example of a user-defined function that operates on lists, consider the problem of counting the number of elements in a list: \bprog \mbox{\tt length\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ [a]\ ->\ Integer}\\ \mbox{\tt length\ []\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ 0}\\ \mbox{\tt length\ (x:xs)\ \ \ \ \ \ \ \ \ \ \ =\ \ 1\ +\ length\ xs} \eprog This definition is almost self-explanatory. We can read the equations as saying: ``The length of the empty list is 0, and the length of a list whose first element is \mbox{\tt x} and remainder is \mbox{\tt xs} is 1 plus the length of \mbox{\tt xs}.'' (Note the naming convention used here; \mbox{\tt xs} is the plural of \mbox{\tt x}, and should be read that way.) Although intuitive, this example highlights an important aspect of Haskell that is yet to be explained: {\em pattern matching}. The left-hand sides of the equations contain patterns such as \mbox{\tt []} and \mbox{\tt x:xs}. In a function application these patterns are matched against actual parameters in a fairly intuitive way (\mbox{\tt []} only matches the empty list, and \mbox{\tt x:xs} will successfully match any list with at least one element, binding \mbox{\tt x} to the first element and \mbox{\tt xs} to the rest of the list). If the match succeeds, the right-hand side is evaluated and returned as the result of the application. If it fails, the next equation is tried, and if all equations fail, an error results. Defining functions by pattern matching is quite common in Haskell, and the user should become familiar with the various kinds of patterns that are allowed; we will return to this issue in Section~\ref{tut-pattern-matching}. The \mbox{\tt length} function is also an example of a polymorphic function. It can be applied to a list containing elements of any type, for example \mbox{\tt [Integer]}, \mbox{\tt [Char]}, or \mbox{\tt [[Integer]]}. \[\ba{lcl} \mbox{\tt length\ [1,2,3]} &\ \ \ \ \red\ \ \ \ & 3\\ \mbox{\tt length\ ['a','b','c']}&\ \ \ \ \red\ \ \ \ & 3\\ \mbox{\tt length\ [[1],[2],[3]]} &\ \ \ \ \red\ \ \ \ & 3 \ea\] Here are two other useful polymorphic functions on lists that will be used later. Function \mbox{\tt head} returns the first element of a list, function \mbox{\tt tail} returns all but the first. \bprog \mbox{\tt head\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ [a]\ ->\ a}\\ \mbox{\tt head\ (x:xs)\ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x}\\ \mbox{\tt }\\[-8pt] \mbox{\tt tail\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ [a]\ ->\ [a]}\\ \mbox{\tt tail\ (x:xs)\ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ xs} \eprog Unlike \mbox{\tt length}, these functions are not defined for all possible values of their argument. A runtime error occurs when these functions are applied to an empty list. With polymorphic types, we find that some types are in a sense strictly more general than others in the sense that the set of values they define is larger. For example, the type \mbox{\tt [a]} is more general than \mbox{\tt [Char]}. In other words, the latter type can be derived from the former by a suitable substitution for \mbox{\tt a}. With regard to this generalization ordering, Haskell's type system possesses two important properties: First, every well-typed expression is guaranteed to have a unique principal type (explained below), and second, the principal type can be inferred automatically (\see{type-semantics}). In comparison to a monomorphically typed language such as C, the reader will find that polymorphism improves expressiveness, and type inference lessens the burden of types on the programmer. An expression's or function's principal type is the least general type that, intuitively, ``contains all instances of the expression''. For example, the principal type of \mbox{\tt head} is \mbox{\tt [a]->a}; \mbox{\tt [b]->a}, \mbox{\tt a->a}, or even \mbox{\tt a} are correct types, but too general, whereas something like \mbox{\tt [Integer]->Integer} is too specific. The existence of unique principal types is the hallmark feature of the {\em Hindley-Milner type system}, which forms the basis of the type systems of Haskell, ML, Miranda,\footnote{``Miranda'' is a trademark of Research Software, Ltd.} and several other (mostly functional) languages. \subsection{User-Defined Types} \label{tut-user-types} We can define our own types in Haskell using a \mbox{\tt data} declaration, which we introduce via a series of examples (\see{datatype-decls}). An important predefined type in Haskell is that of truth values: \bprog \mbox{\tt data\ Bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ False\ |\ True} \eprog The type being defined here is \mbox{\tt Bool}, and it has exactly two values: \mbox{\tt True} and \mbox{\tt False}. Type \mbox{\tt Bool} is an example of a (nullary) {\em type constructor}, and \mbox{\tt True} and \mbox{\tt False} are (also nullary) {\em data constructors} (or just {\em constructors}, for short). Similarly, we might wish to define a color type: \bprog \mbox{\tt data\ Color\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ Red\ |\ Green\ |\ Blue\ |\ Indigo\ |\ Violet} \eprog Both \mbox{\tt Bool} and \mbox{\tt Color} are examples of enumerated types, since they consist of a finite number of nullary data constructors. Here is an example of a type with just one data constructor: \bprog \mbox{\tt data\ Point\ a\ \ \ \ \ \ \ \ \ \ \ \ =\ Pt\ a\ a} \eprog Because of the single constructor, a type like \mbox{\tt Point} is often called a {\em tuple type}, since it is essentially just a cartesian product (in this case binary) of other types.\footnote{Tuples are somewhat like records in other languages.} In contrast, multi-constructor types, such as \mbox{\tt Bool} and \mbox{\tt Color}, are called (disjoint) union or sum types. More importantly, however, \mbox{\tt Point} is an example of a polymorphic type: for any type $t$, it defines the type of cartesian points that use $t$ as the coordinate type. The \mbox{\tt Point} type can now be seen clearly as a unary type constructor, since from the type $t$ it constructs a new type \mbox{\tt Point\ }$t$. (In the same sense, using the list example given earlier, \mbox{\tt []} is also a type constructor. Given any type $t$ we can ``apply'' \mbox{\tt []} to yield a new type \mbox{\tt [}$t$\mbox{\tt ]}. The Haskell syntax allows \mbox{\tt []\ }$t$ to be written as \mbox{\tt [}$t$\mbox{\tt ]}. Similarly, \mbox{\tt ->} is a type constructor: given two types $t$ and $u$, $t$\mbox{\tt ->}$u$ is the type of functions mapping elements of type $t$ to elements of type $u$.) Note that the type of the binary data constructor \mbox{\tt Pt} is \mbox{\tt a\ ->\ a\ ->\ Point\ a}, and thus the following typings are valid: \bprog \mbox{\tt Pt\ \ 2.0\ \ 3.0\ \ \ \ \ \ \ \ \ \ \ \ ::\ Point\ Float}\\ \mbox{\tt Pt\ \ 'a'\ \ 'b'\ \ \ \ \ \ \ \ \ \ \ \ ::\ Point\ Char}\\ \mbox{\tt Pt\ True\ False\ \ \ \ \ \ \ \ \ \ \ ::\ Point\ Bool} \eprog On the other hand, an expression such as \mbox{\tt Pt\ 'a'\ 1} is ill-typed because \mbox{\tt 'a'} and \mbox{\tt 1} are of different types. It is important to distinguish between applying a {\em data constructor} to yield a {\em value}, and applying a {\em type constructor} to yield a {\em type}; the former happens at run-time and is how we compute things in Haskell, whereas the latter happens at compile-time and is part of the type system's process of ensuring type safety. \syn{Type constructors such as \mbox{\tt Point} and data constructors such as \mbox{\tt Pt} are in separate namespaces. This allows the same name to be used for both a type constructor and data constructor, as in the following: \bprog \mbox{\tt data\ Point\ a\ =\ Point\ a\ a} \eprog While this may seem a little confusing at first, it serves to make the link between a type and its data constructor more obvious.} \subsubsection{Recursive Types} \label{tut-recursive-types} Types can also be recursive, as in the type of binary trees: \bprog \mbox{\tt data\ Tree\ a\ \ \ \ \ \ \ \ \ \ \ \ \ =\ Leaf\ a\ |\ Branch\ (Tree\ a)\ (Tree\ a)\ } \eprog Here we have defined a polymorphic binary tree type whose elements are either leaf nodes containing a value of type \mbox{\tt a}, or internal nodes (``branches'') containing (recursively) two sub-trees. When reading data declarations such as this, remember again that \mbox{\tt Tree} is a type constructor, whereas \mbox{\tt Branch} and \mbox{\tt Leaf} are data constructors. Aside from establishing a connection between these constructors, the above declaration is essentially defining the following types for \mbox{\tt Branch} and \mbox{\tt Leaf}: \bprog \mbox{\tt Branch\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Tree\ a\ ->\ Tree\ a\ ->\ Tree\ a}\\ \mbox{\tt Leaf\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ Tree\ a} \eprog With this example we have defined a type sufficiently rich to allow defining some interesting (recursive) functions that use it. For example, suppose we wish to define a function \mbox{\tt fringe} that returns a list of all the elements in the leaves of a tree from left to right. It's usually helpful to write down the type of new functions first; in this case we see that the type should be \mbox{\tt Tree\ a\ ->\ [a]}. That is, \mbox{\tt fringe} is a polymorphic function that, for any type \mbox{\tt a}, maps trees of \mbox{\tt a} into lists of \mbox{\tt a}. A suitable definition follows: \bprog \mbox{\tt fringe\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Tree\ a\ ->\ [a]}\\ \mbox{\tt fringe\ (Leaf\ x)\ \ \ \ \ \ \ \ \ \ \ \ =\ \ [x]}\\ \mbox{\tt fringe\ (Branch\ left\ right)\ =\ \ fringe\ left\ ++\ fringe\ right} \eprog Here \mbox{\tt ++} is the infix operator that concatenates two lists (its full definition will be given in Section \ref{tut-monadic-classes}). As with the \mbox{\tt length} example given earlier, the \mbox{\tt fringe} function is defined using pattern matching, except that here we see patterns involving user-defined constructors: \mbox{\tt Leaf} and \mbox{\tt Branch}. \syn{Note that the formal parameters are easily identified as the ones beginning with lower-case letters.} \subsection{Type Synonyms} \label{tut-type-synonyms} For convenience, Haskell provides a way to define {\em type synonyms}; i.e.~names for commonly used types. Type synonyms are created using a \mbox{\tt type} declaration (\see{type-synonym-decls}). Here are several examples: \bprog \mbox{\tt type\ String\ \ \ \ \ \ \ \ \ \ \ \ \ =\ [Char]}\\ \mbox{\tt type\ Person\ \ \ \ \ \ \ \ \ \ \ \ \ =\ (Name,Address)}\\ \mbox{\tt type\ Name\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ String}\\ \mbox{\tt data\ Address\ \ \ \ \ \ \ \ \ \ \ \ =\ None\ |\ Addr\ String} \eprog Type synonyms do not define new types, but simply give new names for existing types. For example, the type \mbox{\tt Person\ ->\ Name} is precisely equivalent to \mbox{\tt (String,Address)\ ->\ String}. The new names are often shorter than the types they are synonymous with, but this is not the only purpose of type synonyms: they can also improve readability of programs by being more mnemonic; indeed, the above examples highlight this. We can even give new names to polymorphic types: \bprog \mbox{\tt type\ AssocList\ a\ b\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ [(a,b)]} \eprog This is the type of ``association lists'' which associate values of type \mbox{\tt a} with those of type \mbox{\tt b}. \subsection{Built-in Types Are Not Special} \label{tut-built-ins} Earlier we introduced several ``built-in'' types such as lists, tuples, integers, and characters. We have also shown how new user-defined types can be defined. Aside from special syntax, are the built-in types in any way more special than the user-defined ones? The answer is {\em no}. The special syntax is for convenience and for consistency with historical convention, but has no semantic consequences. We can emphasize this point by considering what the type declarations would look like for these built-in types if in fact we were allowed to use the special syntax in defining them. For example, the \mbox{\tt Char} type might be written as: \bprog \mbox{\tt data\ Char\ \ \ \ \ \ \ =\ 'a'\ |\ 'b'\ |\ 'c'\ |\ ...\ \ \ \ \ \ \ \ \ --\ This\ is\ not\ valid}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ 'A'\ |\ 'B'\ |\ 'C'\ |\ ...\ \ \ \ \ \ \ \ \ --\ Haskell\ code!}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ '1'\ |\ '2'\ |\ '3'\ |\ ...}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ...} \eprog These constructor names are not syntactically valid; to fix them we would have to write something like: \bprog \mbox{\tt data\ Char\ \ \ \ \ \ \ =\ Ca\ |\ Cb\ |\ Cc\ |\ ...}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ CA\ |\ CB\ |\ CC\ |\ ...}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ C1\ |\ C2\ |\ C3\ |\ ...}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ...} \eprog Even though these constructors are more concise, they are quite unconventional for representing characters. In any case, writing ``pseudo-Haskell'' code in this way helps us to see through the special syntax. We see now that \mbox{\tt Char} is just an enumerated type consisting of a large number of nullary constructors. Thinking of \mbox{\tt Char} in this way makes it clear that we can pattern-match against characters in function definitions, just as we would expect to be able to do so for any of a type's constructors. \syn{This example also demonstrates the use of {\em comments} in Haskell; the characters \mbox{\tt --} and all subsequent characters to the end of the line are ignored. Haskell also permits {\em nested} comments which have the form \mbox{\tt {\char'173}-}$\ldots$\mbox{\tt -{\char'175}} and can appear anywhere (\see{lexemes}).} Similarly, we could define \mbox{\tt Int} (fixed precision integers) and \mbox{\tt Integer} by: \bprog \mbox{\tt data\ Int\ \ \ \ \ =\ -65532\ |\ ...\ |\ -1\ |\ 0\ |\ 1\ |\ ...\ |\ 65532\ \ --\ more\ pseudo-code}\\ \mbox{\tt data\ Integer\ =\ \ \ \ \ \ \ ...\ -2\ |\ -1\ |\ 0\ |\ 1\ |\ 2\ ...} \eprog where \mbox{\tt -65532} and \mbox{\tt 65532}, say, are the maximum and minimum fixed precision integers for a given implementation. \mbox{\tt Int} is a much larger enumeration than \mbox{\tt Char}, but it's still finite! In contrast, the pseudo-code for \mbox{\tt Integer} is intended to convey an {\em infinite} enumeration. Tuples are also easy to define playing this game: \bprog \mbox{\tt data\ (a,b)\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ (a,b)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ --\ more\ pseudo-code}\\ \mbox{\tt data\ (a,b,c)\ \ \ \ \ \ \ \ \ \ \ \ =\ (a,b,c)}\\ \mbox{\tt data\ (a,b,c,d)\ \ \ \ \ \ \ \ \ \ =\ (a,b,c,d)}\\ \mbox{\tt \ .\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .}\\ \mbox{\tt \ .\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .}\\ \mbox{\tt \ .\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .} \eprog Each declaration above defines a tuple type of a particular length, with \mbox{\tt (...)} playing a role in both the expression syntax (as data constructor) and type-expression syntax (as type constructor). The vertical dots after the last declaration are intended to convey an infinite number of such declarations, reflecting the fact that tuples of all lengths are allowed in Haskell. Lists are also easily handled, and more interestingly, they are recursive: \bprog \mbox{\tt \ data\ [a]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ []\ |\ a\ :\ [a]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ --\ more\ pseudo-code} \eprog We can now see clearly what we described about lists earlier: \mbox{\tt []} is the empty list, and \mbox{\tt :} is the infix list constructor; thus \mbox{\tt [1,2,3]} must be equivalent to the list \mbox{\tt 1:2:3:[]}. (\mbox{\tt :} is right associative.) The type of \mbox{\tt []} is \mbox{\tt [a]}, and the type of \mbox{\tt :} is \mbox{\tt a->[a]->[a]}. \syn{The way ``\mbox{\tt :}'' is defined here is actually legal syntax---infix constructors are permitted in \mbox{\tt data} declarations, and are distinguished from infix operators (for pattern-matching purposes) by the fact that they must begin with a ``\mbox{\tt :}'' (a property trivially satisfied by ``\mbox{\tt :}'').} At this point the reader should note carefully the differences between tuples and lists, which the above definitions make abundantly clear. In particular, note the recursive nature of the list type whose elements are homogeneous and of arbitrary length, and the non-recursive nature of a (particular) tuple type whose elements are heterogeneous and of fixed length. The typing rules for tuples and lists should now also be clear: For $\mbox{\tt (}e_1\mbox{\tt ,}e_2\mbox{\tt ,}\ldots\mbox{\tt ,}e_n\mbox{\tt )},\ n\geq2$, if $t_i$ is the type of $e_i$, then the type of the tuple is $\mbox{\tt (}t_1\mbox{\tt ,}t_2\mbox{\tt ,}\ldots\mbox{\tt ,}t_n\mbox{\tt )}$. For $\mbox{\tt [}e_1\mbox{\tt ,}e_2\mbox{\tt ,}\ldots\mbox{\tt ,}e_n\mbox{\tt ]},\ n\geq0$, each $e_i$ must have the same type $t$, and the type of the list is \mbox{\tt [}$t$\mbox{\tt ]}. \subsubsection{List Comprehensions and Arithmetic Sequences} \label{tut-list-comps} As with Lisp dialects, lists are pervasive in Haskell, and as with other functional languages, there is yet more syntactic sugar to aid in their creation. Aside from the constructors for lists just discussed, Haskell provides an expression known as a {\em list comprehension} that is best explained by example: \bprog \mbox{\tt [\ f\ x\ |\ x\ <-\ xs\ ]} \eprog This expression can intuitively be read as ``the list of all \mbox{\tt f\ x} such that \mbox{\tt x} is drawn from \mbox{\tt xs}.'' The similarity to set notation is not a coincidence. The phrase \mbox{\tt x\ <-\ xs} is called a {\em generator}, of which more than one is allowed, as in: \bprog \mbox{\tt [\ (x,y)\ |\ x\ <-\ xs,\ y\ <-\ ys\ ]} \eprog This list comprehension forms the cartesian product of the two lists \mbox{\tt xs} and \mbox{\tt ys}. The elements are selected as if the generators were ``nested'' from left to right (with the rightmost generator varying fastest); thus, if \mbox{\tt xs} is \mbox{\tt [1,2]} and \mbox{\tt ys} is \mbox{\tt [3,4]}, the result is \mbox{\tt [(1,3),(1,4),(2,3),(2,4)]}. Besides generators, boolean expressions called {\em guards} are permitted. Guards place constraints on the elements generated. For example, here is a concise definition of everybody's favorite sorting algorithm: \bprog \mbox{\tt quicksort\ \ []\ \ \ \ \ \ \ \ \ \ \ =\ \ []}\\ \mbox{\tt quicksort\ (x:xs)\ \ \ \ \ \ \ \ =\ \ quicksort\ [y\ |\ y\ <-\ xs,\ y=x]} \eprog To further support the use of lists, Haskell has special syntax for {\em arithmetic sequences}, which are best explained by a series of examples: \[\ba{lcl} \mbox{\tt [1..10]} \ \ \ &\red&\ \ \ \mbox{\tt [1,2,3,4,5,6,7,8,9,10]}\\ \mbox{\tt [1,3..10]}\ \ \ &\red&\ \ \ \mbox{\tt [1,3,5,7,9]}\\ % \mbox{\tt [1..]} \ \ \ &\red&\ \ \ \mbox{\tt [1,2,3,4,5,\ ...}\ \ \ \ \ % \mbox{(infinite sequence)}\\ \mbox{\tt [1,3..]} \ \ \ &\red&\ \ \ \mbox{\tt [1,3,5,7,9,\ ...}\ \ \ \ \ \mbox{(infinite sequence)}\\ \ea\] More will be said about arithmetic sequences in Section \ref{tut-enum-classes}, and ``infinite lists'' in Section \ref{tut-infinite}. \subsubsection{Strings} \label{tut-strings} As another example of syntactic sugar for built-in types, we note that the literal string \mbox{\tt "hello"} is actually shorthand for the list of characters \mbox{\tt ['h','e','l','l','o']}. Indeed, the type of \mbox{\tt "hello"} is \mbox{\tt String}, where \mbox{\tt String} is a predefined type synonym (that we gave as an earlier example): \bprog \mbox{\tt type\ String\ \ \ \ \ \ \ \ \ \ \ \ \ =\ [Char]} \eprog This means we can use predefined polymorphic list functions to operate on strings. For example: \[ \mbox{\tt "hello"\ ++\ "\ world"}\ \ \ \ \red\ \ \ \ \mbox{\tt "hello\ world"} \] %**~footer haskell-98-tutorial-sources/functions.tex0100644000106400000620000003721507116002314017136 0ustar jcpftp%**A Gentle Introduction to Haskell: Functions %**~header %%% \section{Functions} \label{tut-functions} Since Haskell is a functional language, one would expect functions to play a major role, and indeed they do. In this section, we look at several aspects of functions in Haskell. First, consider this definition of a function which adds its two arguments: \bprog \mbox{\tt add\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Integer\ ->\ Integer\ ->\ Integer}\\ \mbox{\tt add\ x\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ +\ y} \eprog This is an example of a {\em curried} function.\footnote{The name {\em curry} derives from the person who popularized the idea: Haskell Curry. To get the effect of an {\em uncurried} function, we could use a {\em tuple}, as in: \bprog \mbox{\tt add\ (x,y)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ x\ +\ y} \eprog But then we see that this version of \mbox{\tt add} is really just a function of one argument!} An application of \mbox{\tt add} has the form \mbox{\tt add\ }$e_1\ e_2$, and is equivalent to \mbox{\tt (add\ }$e_1$\mbox{\tt )\ }$e_2$, since function application associates to the {\em left}. In other words, applying \mbox{\tt add} to one argument yields a new function which is then applied to the second argument. This is consistent with the type of \mbox{\tt add}, \mbox{\tt Integer->Integer->Integer}, which is equivalent to \mbox{\tt Integer->(Integer->Integer)}; i.e.~\mbox{\tt ->} associates to the {\em right}. Indeed, using \mbox{\tt add}, we can define \mbox{\tt inc} in a different way from earlier: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ add\ 1} \eprog This is an example of the {\em partial application} of a curried function, and is one way that a function can be returned as a value. Let's consider a case in which it's useful to pass a function as an argument. The well-known \mbox{\tt map} function is a perfect example: \bprog \mbox{\tt map\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (a->b)\ ->\ [a]\ ->\ [b]}\\ \mbox{\tt map\ f\ \ []\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ []}\\ \mbox{\tt map\ f\ (x:xs)\ \ \ \ \ \ \ \ \ \ \ \ =\ \ f\ x\ :\ map\ f\ xs} \eprog \syn{Function application has higher precedence than any infix operator, and thus the right-hand side of the second equation parses as \mbox{\tt (f\ x)\ :\ (map\ f\ xs)}.}\ \ \ The \mbox{\tt map} function is polymorphic and its type indicates clearly that its first argument is a function; note also that the two \mbox{\tt a}'s must be instantiated with the same type (likewise for the \mbox{\tt b}'s). As an example of the use of \mbox{\tt map}, we can increment the elements in a list: \[ \mbox{\tt map\ (add\ 1)\ [1,2,3]}\ \ \ \ \red\ \ \ \ \mbox{\tt [2,3,4]} \] These examples demonstrate the first-class nature of functions, which when used in this way are usually called {\em higher-order} functions. \subsection{Lambda Abstractions} \label{tut-lambda} Instead of using equations to define functions, we can also define them ``anonymously'' via a {\em lambda abstraction}. For example, a function equivalent to \mbox{\tt inc} could be written as \mbox{\tt {\char'134}x\ ->\ x+1}. Similarly, the function \mbox{\tt add} is equivalent to \mbox{\tt {\char'134}x\ ->\ {\char'134}y\ ->\ x+y}. Nested lambda abstractions such as this may be written using the equivalent shorthand notation \mbox{\tt {\char'134}x\ y\ ->\ x+y}. In fact, the equations: \bprog \mbox{\tt inc\ x\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ x+1}\\ \mbox{\tt add\ x\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ x+y} \eprog are really shorthand for: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ {\char'134}x\ \ \ ->\ x+1}\\ \mbox{\tt add\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ {\char'134}x\ y\ ->\ x+y} \eprog We will have more to say about such equivalences later. In general, given that \mbox{\tt x} has type $t_1$ and \mbox{\tt exp} has type $t_2$, then \mbox{\tt {\char'134}x->exp} has type $t_1$\mbox{\tt ->}$t_2$. \subsection{Infix Operators} \label{tut-infix-ops} Infix operators are really just functions, and can also be defined using equations. For example, here is a definition of a list concatenation operator: \bprog \mbox{\tt (++)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ [a]\ ->\ [a]\ ->\ [a]}\\ \mbox{\tt []\ \ \ \ \ ++\ ys\ \ \ \ \ \ \ \ \ \ \ \ =\ \ ys}\\ \mbox{\tt (x:xs)\ ++\ ys\ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ :\ (xs++ys)} \eprog \syn{Lexically, infix operators consist entirely of ``symbols,'' as opposed to normal identifiers which are alphanumeric (\see{ids}). Haskell has no prefix operators, with the exception of minus (\mbox{\tt -}), which is both infix and prefix.} As another example, an important infix operator on functions is that for {\em function composition}: \bprog \mbox{\tt (.)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (b->c)\ ->\ (a->b)\ ->\ (a->c)}\\ \mbox{\tt f\ .\ g\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ {\char'134}\ x\ ->\ f\ (g\ x)} \eprog \subsubsection{Sections} \label{tut-sections} Since infix operators are really just functions, it makes sense to be able to partially apply them as well. In Haskell the partial application of an infix operator is called a {\em section}. For example: \[\ba{ccc} \mbox{\tt (x+)}\ \ \ \ &\equiv&\ \ \ \ \mbox{\tt {\char'134}y\ ->\ x+y} \\ \mbox{\tt (+y)}\ \ \ \ &\equiv&\ \ \ \ \mbox{\tt {\char'134}x\ ->\ x+y} \\ \mbox{\tt (+)} \ \ \ \ &\equiv&\ \ \ \ \mbox{\tt {\char'134}x\ y\ ->\ x+y} \ea\] \syn{The parentheses are mandatory.} The last form of section given above essentially coerces an infix operator into an equivalent functional value, and is handy when passing an infix operator as an argument to a function, as in \mbox{\tt map\ (+)\ [1,2,3]} (the reader should verify that this returns a list of functions!). It is also necessary when giving a function type signature, as in the examples of \mbox{\tt (++)} and \mbox{\tt (.)} given earlier. We can now see that \mbox{\tt add} defined earlier is just \mbox{\tt (+)}, and \mbox{\tt inc} is just \mbox{\tt (+1)}! Indeed, these definitions would do just fine: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ (+\ 1)}\\ \mbox{\tt add\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ (+)} \eprog We can coerce an infix operator into a functional value, but can we go the other way? Yes---we simply enclose an identifier bound to a functional value in backquotes. For example, \mbox{\tt x\ `add`\ y} is the same as \mbox{\tt add\ x\ y}.\footnote{Note carefully that \mbox{\tt add} is enclosed in {\em backquotes}, not {\em apostrophes} as used in the syntax of characters; i.e. \mbox{\tt 'f'} is a character, whereas \mbox{\tt `f`} is an infix operator. Fortunately, most ASCII terminals distinguish these much better than the font used in this manuscript.} Some functions read better this way. An example is the predefined list membership predicate \mbox{\tt elem}; the expression \mbox{\tt x\ `elem`\ xs} can be read intuitively as ``\mbox{\tt x} is an element of \mbox{\tt xs}.'' \syn{There are some special rules regarding sections involving the prefix/infix operator \mbox{\tt -}; see (\see{sections},\see{operators}).} At this point, the reader may be confused at having so many ways to define a function! The decision to provide these mechanisms partly reflects historical conventions, and partly reflects the desire for consistency (for example, in the treatment of infix vs. regular functions). % That's all right---the designers of Haskell are too. \subsubsection{Fixity Declarations} A {\em fixity declaration} can be given for any infix operator or constructor (including those made from ordinary identifiers, such as \mbox{\tt `elem`}). %\footnote{Fixity declarations must only appear at the very %beginning of a Haskell {\em module}, as will be described in Section %\ref{tut-modules}.} This declaration specifies a precedence level from 0 to 9 (with 9 being the strongest; normal application is assumed to have a precedence level of 10), and left-, right-, or non-associativity. For example, the fixity declarations for \mbox{\tt ++} and \mbox{\tt .} are: \bprog \mbox{\tt infixr\ 5\ ++}\\ \mbox{\tt infixr\ 9\ .} \eprog Both of these specify right-associativity, the first with a precedence level of 5, the other 9. Left associativity is specified via \mbox{\tt infixl}, and non-associativity by \mbox{\tt infix}. Also, the fixity of more than one operator may be specified with the same fixity declaration. If no fixity declaration is given for a particular operator, it defaults to \mbox{\tt infixl\ 9}. (See \see{fixity} for a detailed definition of the associativity rules.) \subsection{Functions are Non-strict} \label{tut-non-strict} Suppose \mbox{\tt bot} is defined by: \bprog \mbox{\tt bot\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ bot} \eprog In other words, \mbox{\tt bot} is a non-terminating expression. Abstractly, we denote the {\em value} of a non-terminating expression as $\bot$ (read ``bottom''). Expressions that result in some kind of a run-time error, such as \mbox{\tt 1/0}, also have this value. Such an error is not recoverable: programs will not continue past these errors. Errors encountered by the I/O system, such as an end-of-file error, are recoverable and are handled in a different manner. (Such an I/O error is really not an error at all but rather an exception. Much more will be said about exceptions in Section \ref{tut-io}.) A function \mbox{\tt f} is said to be {\em strict} if, when applied to a nonterminating expression, it also fails to terminate. In other words, \mbox{\tt f} is strict iff the value of \mbox{\tt f\ bot} is $\bot$. For most programming languages, {\em all} functions are strict. But this is not so in Haskell. As a simple example, consider \mbox{\tt const1}, the constant 1 function, defined by: \bprog \mbox{\tt const1\ x\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ 1} \eprog The value of \mbox{\tt const1\ bot} in Haskell is \mbox{\tt 1}. Operationally speaking, since \mbox{\tt const1} does not ``need'' the value of its argument, it never attempts to evaluate it, and thus never gets caught in a nonterminating computation. For this reason, non-strict functions are also called ``lazy functions'', and are said to evaluate their arguments ``lazily'', or ``by need''. Since error and nonterminating values are semantically the same in Haskell, the above argument also holds for errors. For example, \mbox{\tt const1\ (1/0)} also evaluates properly to \mbox{\tt 1}. Non-strict functions are extremely useful in a variety of contexts. The main advantage is that they free the programmer from many concerns about evaluation order. Computationally expensive values may be passed as arguments to functions without fear of them being computed if they are not needed. An important example of this is a possibly {\em infinite} data structure. Another way of explaining non-strict functions is that Haskell computes using \mbox{$\it definitions$} rather than the \mbox{$\it assignments$} found in traditional languages. Read a declaration such as \bprog \mbox{\tt v\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ 1/0\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } \eprog as `define \mbox{\tt v} as \mbox{\tt 1/0}' instead of `compute \mbox{\tt 1/0} and store the result in \mbox{\tt v}'. Only if the value (definition) of \mbox{\tt v} is needed will the division by zero error occur. By itself, this declaration does not imply any computation. Programming using assignments requires careful attention to the ordering of the assignments: the meaning of the program depends on the order in which the assignments are executed. Definitions, in contrast, are much simpler: they can be presented in any order without affecting the meaning of the program. \subsection{``Infinite'' Data Structures} \label{tut-infinite} One advantage of the non-strict nature of Haskell is that data constructors are non-strict, too. This should not be surprising, since constructors are really just a special kind of function (the distinguishing feature being that they can be used in pattern matching). For example, the constructor for lists, \mbox{\tt (:)}, is non-strict. Non-strict constructors permit the definition of (conceptually) {\em infinite} data structures. Here is an infinite list of ones: \bprog \mbox{\tt ones\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ 1\ :\ ones} \eprog Perhaps more interesting is the function \mbox{\tt numsFrom}: \bprog \mbox{\tt numsFrom\ n\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ n\ :\ numsFrom\ (n+1)} \eprog Thus \mbox{\tt numsFrom\ n} is the infinite list of successive integers beginning with \mbox{\tt n}. From it we can construct an infinite list of squares: \bprog \mbox{\tt squares\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ map\ ({\char'136}2)\ (numsfrom\ 0)} \eprog (Note the use of a section; \mbox{\tt {\char'136}} is the infix exponentiation operator.) Of course, eventually we expect to extract some finite portion of the list for actual computation, and there are lots of predefined functions in Haskell that do this sort of thing: \mbox{\tt take}, \mbox{\tt takeWhile}, \mbox{\tt filter}, and others. The definition of Haskell includes a large set of built-in functions and types---this is called the ``Standard Prelude''. The complete Standard Prelude is included in Appendix A of the Haskell report; see the portion named \mbox{\tt PreludeList} for many useful functions involving lists. For example, \mbox{\tt take} removes the first \mbox{\tt n} elements from a list: \[ \mbox{\tt take\ 5\ squares}\ \ \ \ \red\ \ \ \ \mbox{\tt [0,1,4,9,16]} \] The definition of \mbox{\tt ones} above is an example of a {\em circular list}. In most circumstances laziness has an important impact on efficiency, since an implementation can be expected to implement the list as a true circular structure, thus saving space. For another example of the use of circularity, the Fibonacci sequence can be computed efficiently as the following infinite sequence: \bprog \mbox{\tt fib\ \ \ \ \ \ \ \ \ \ \ \ \ =\ 1\ :\ 1\ :\ [\ a+b\ |\ (a,b)\ <-\ zip\ fib\ (tail\ fib)\ ]} \eprog where \mbox{\tt zip} is a Standard Prelude function that returns the pairwise interleaving of its two list arguments: \bprog \mbox{\tt zip\ (x:xs)\ (y:ys)\ \ \ \ \ \ \ =\ (x,y)\ :\ zip\ xs\ ys}\\ \mbox{\tt zip\ \ xs\ \ \ \ \ ys\ \ \ \ \ \ \ \ \ \ =\ []} \eprog Note how \mbox{\tt fib}, an infinite list, is defined in terms of itself, as if it were ``chasing its tail.'' Indeed, we can draw a picture of this computation as shown in Figure \ref{tut-fib-fig}. %**
    \mbox{$\it %**

    Figure 1

    For another application of infinite lists, see Section \ref{tut-lazy-patterns}. %*ignore \begin{figure} \begin{center} \mbox{ {\epsfxsize=2.5in \epsfbox{fig1.eps}}} \end{center} \caption{Circular Fibonacci Sequence} \label{tut-fib-fig} \end{figure} %*endignore \subsection{The Error Function} Haskell has a built-in function called \mbox{\tt error} whose type is \mbox{\tt String->a}. This is a somewhat odd function: From its type it looks as if it is returning a value of a polymorphic type about which it knows nothing, since it never receives a value of that type as an argument! In fact, there {\em is} one value ``shared'' by all types: $\bot$. Indeed, semantically that is exactly what value is always returned by \mbox{\tt error} (recall that all errors have value $\bot$). However, we can expect that a reasonable implementation will print the string argument to \mbox{\tt error} for diagnostic purposes. Thus this function is useful when we wish to terminate a program when something has ``gone wrong.'' For example, the actual definition of \mbox{\tt head} taken from the Standard Prelude is: \bprog \mbox{\tt head\ (x:xs)\ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x}\\ \mbox{\tt head\ \ []\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ error\ "head{\char'173}PreludeList{\char'175}:\ head\ []"} \eprog %**~footer haskell-98-tutorial-sources/patterns.tex0100644000106400000620000004732407116002315016771 0ustar jcpftp%**A Gentle Introduction to Haskell: Patterns %**~header \section{Case Expressions and Pattern Matching} \label{tut-pattern-matching} Earlier we gave several examples of pattern matching in defining functions---for example \mbox{\tt length} and \mbox{\tt fringe}. In this section we will look at the pattern-matching process in greater detail (\see{pattern-matching}).\footnote{Pattern matching in Haskell is different from that found in logic programming languages such as Prolog; in particular, it can be viewed as ``one-way'' matching, whereas Prolog allows ``two-way'' matching (via unification), along with implicit backtracking in its evaluation mechanism.} Patterns are not ``first-class;'' there is only a fixed set of different kinds of patterns. We have already seen several examples of {\em data constructor} patterns; both \mbox{\tt length} and \mbox{\tt fringe} defined earlier use such patterns, the former on the constructors of a ``built-in'' type (lists), the latter on a user-defined type (\mbox{\tt Tree}). Indeed, matching is permitted using the constructors of any type, user-defined or not. This includes tuples, strings, numbers, characters, etc. For example, here's a contrived function that matches against a tuple of ``constants:'' \bprog \mbox{\tt contrived\ ::\ ([a],\ Char,\ (Int,\ Float),\ String,\ Bool)\ ->\ Bool}\\ \mbox{\tt contrived\ \ \ \ ([],\ \ 'b',\ \ (1,\ \ \ 2.0),\ \ \ "hi",\ \ \ True)\ =\ False} \eprog This example also demonstrates that {\em nesting} of patterns is permitted (to arbitrary depth). Technically speaking, {\em formal parameters}\footnote{The Report calls these {\em variables}.} are also patterns---it's just that they {\em never fail to match a value}. As a ``side effect'' of the successful match, the formal parameter is bound to the value it is being matched against. For this reason patterns in any one equation are not allowed to have more than one occurrence of the same formal parameter (a property called {\em linearity} \see{pattern-matching}, \see{lambda-abstractions}, \see{function-bindings}). Patterns such as formal parameters that never fail to match are said to be {\em irrefutable}, in contrast to {\em refutable} patterns which may fail to match. The pattern used in the \mbox{\tt contrived} example above is refutable. There are three other kinds of irrefutable patterns, two of which we will introduce now (the other we will delay until Section \ref{tut-lazy-patterns}). \paragraph*{As-patterns.} Sometimes it is convenient to name a pattern for use on the right-hand side of an equation. For example, a function that duplicates the first element in a list might be written as: \bprog \mbox{\tt f\ (x:xs)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ x:x:xs} \eprog (Recall that ``\mbox{\tt :}'' associates to the right.) Note that \mbox{\tt x:xs} appears both as a pattern on the left-hand side, and an expression on the right-hand side. To improve readability, we might prefer to write \mbox{\tt x:xs} just once, which we can achieve using an {\em as-pattern} as follows:\footnote{Another advantage to doing this is that a naive implementation might completely reconstruct \mbox{\tt x:xs} rather than re-use the value being matched against.} \bprog \mbox{\tt f\ s@(x:xs)\ \ \ \ \ \ \ \ \ \ \ \ \ =\ x:s} \eprog Technically speaking, as-patterns always result in a successful match, although the sub-pattern (in this case \mbox{\tt x:xs}) could, of course, fail. \paragraph*{Wild-cards.} Another common situation is matching against a value we really care nothing about. For example, the functions \mbox{\tt head} and \mbox{\tt tail} defined in Section \ref{tut-polymorphism} can be rewritten as: \bprog \mbox{\tt head\ (x:{\char'137})\ \ \ \ \ \ \ \ \ \ \ \ \ =\ x}\\ \mbox{\tt tail\ ({\char'137}:xs)\ \ \ \ \ \ \ \ \ \ \ \ =\ xs} \eprog in which we have ``advertised'' the fact that we don't care what a certain part of the input is. Each wild-card independently matches anything, but in contrast to a formal parameter, each binds nothing; for this reason more than one is allowed in an equation. \subsection{Pattern-Matching Semantics} \label{tut-matching-semantics} So far we have discussed how individual patterns are matched, how some are refutable, some are irrefutable, etc. But what drives the overall process? In what order are the matches attempted? What if none succeeds? This section addresses these questions. Pattern matching can either {\em fail}, {\em succeed} or {\em diverge}. A successful match binds the formal parameters in the pattern. Divergence occurs when a value needed by the pattern contains an error ($\bot$). The matching process itself occurs ``top-down, left-to-right.'' Failure of a pattern anywhere in one equation results in failure of the whole equation, and the next equation is then tried. If all equations fail, the value of the function application is $\bot$, and results in a run-time error. For example, if \mbox{\tt [1,2]} is matched against \mbox{\tt [0,bot]}, then \mbox{\tt 1} fails to match \mbox{\tt 0}, so the result is a failed match. (Recall that \mbox{\tt bot}, defined earlier, is a variable bound to $\bot$.) But if \mbox{\tt [1,2]} is matched against \mbox{\tt [bot,0]}, then matching \mbox{\tt 1} against \mbox{\tt bot} causes divergence (i.e.~$\bot$). The other twist to this set of rules is that top-level patterns may also have a boolean {\em guard}, as in this definition of a function that forms an abstract version of a number's sign: \bprog \mbox{\tt sign\ x\ |\ \ x\ >\ \ 0\ \ \ \ \ \ \ \ =\ \ \ 1}\\ \mbox{\tt \ \ \ \ \ \ \ |\ \ x\ ==\ 0\ \ \ \ \ \ \ \ =\ \ \ 0}\\ \mbox{\tt \ \ \ \ \ \ \ |\ \ x\ <\ \ 0\ \ \ \ \ \ \ \ =\ \ -1} \eprog Note that a sequence of guards may be provided for the same pattern; as with patterns, they are evaluated top-down, and the first that evaluates to \mbox{\tt True} results in a successful match. \subsection{An Example} The pattern-matching rules can have subtle effects on the meaning of functions. For example, consider this definition of \mbox{\tt take}: \bprog \mbox{\tt take\ \ 0\ \ \ \ \ {\char'137}\ \ \ \ \ \ \ \ \ \ \ =\ \ []}\\ \mbox{\tt take\ \ {\char'137}\ \ \ \ \ []\ \ \ \ \ \ \ \ \ \ =\ \ []}\\ \mbox{\tt take\ \ n\ \ \ \ \ (x:xs)\ \ \ \ \ \ =\ \ x\ :\ take\ (n-1)\ xs} \eprog and this slightly different version (the first 2 equations have been reversed): \bprog \mbox{\tt take1\ \ {\char'137}\ \ \ \ \ []\ \ \ \ \ \ \ \ \ =\ \ []}\\ \mbox{\tt take1\ \ 0\ \ \ \ \ {\char'137}\ \ \ \ \ \ \ \ \ \ =\ \ []}\\ \mbox{\tt take1\ \ n\ \ \ \ (x:xs)\ \ \ \ \ \ =\ \ x\ :\ take1\ (n-1)\ xs} \eprog Now note the following: \[\ba{lcl} \mbox{\tt take\ \ 0\ bot} &\ \ \ \red\ \ \ & \mbox{\tt []} \\ \mbox{\tt take1\ 0\ bot} &\ \ \ \red\ \ \ & \bot \\[.1in] \mbox{\tt take\ \ bot\ []} &\ \ \ \red\ \ \ & \bot \\ \mbox{\tt take1\ bot\ []} &\ \ \ \red\ \ \ & \mbox{\tt []} \ea\] We see that \mbox{\tt take} is ``more defined'' with respect to its second argument, whereas \mbox{\tt take1} is more defined with respect to its first. It is difficult to say in this case which definition is better. Just remember that in certain applications, it may make a difference. (The Standard Prelude includes a definition corresponding to \mbox{\tt take}.) \subsection{Case Expressions} \label{tut-case} Pattern matching provides a way to ``dispatch control'' based on structural properties of a value. In many circumstances we don't wish to define a {\em function} every time we need to do this, but so far we have only shown how to do pattern matching in function definitions. Haskell's {\em case expression} provides a way to solve this problem. Indeed, the meaning of pattern matching in function definitions is specified in the Report in terms of case expressions, which are considered more primitive. In particular, a function definition of the form: \[\ba{l} \mbox{$\it \makebox{\tt f}\ p_{11}\ \ldots \ p_{1k}\ \makebox{\tt =}\ e_{1}$} \\ \mbox{$\it \ldots $} \\ \mbox{$\it \makebox{\tt f}\ p_{n1}\ \ldots \ p_{nk}\ \makebox{\tt =}\ e_{n}$} \ea\] where each \mbox{$\it p_{ij}$} is a pattern, is semantically equivalent to: \[ \mbox{$\it \makebox{\tt f\ x1\ x2}\ \ldots \ \makebox{\tt xk\ =\ case\ (x1,\ }\ldots \makebox{\tt ,\ xk)\ of}$} \ba[t]{l} \mbox{$\it \makebox{\tt (}p_{11},\ \ldots ,\ p_{1k}\makebox{\tt )\ ->}\ e_{1}$} \\ \mbox{$\it \ldots $} \\ \mbox{$\it \makebox{\tt (}p_{n1},\ \ldots ,\ p_{nk}\makebox{\tt )\ ->}\ e_{n}$} \ea \] where the \mbox{\tt xi} are new identifiers. (For a more general translation that includes guards, see \see{function-bindings}.) For example, the definition of \mbox{\tt take} given earlier is equivalent to: \bprog \mbox{\tt take\ m\ ys\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ case\ (m,ys)\ of}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (0,{\char'137})\ \ \ \ \ \ \ ->\ \ []}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ({\char'137},[])\ \ \ \ \ \ ->\ \ []}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (n,x:xs)\ \ \ \ ->\ \ x\ :\ take\ (n-1)\ xs} \eprog A point not made earlier is that, for type correctness, the types of the right-hand sides of a case expression or set of equations comprising a function definition must all be the same; more precisely, they must all share a common principal type. The pattern-matching rules for case expressions are the same as we have given for function definitions, so there is really nothing new to learn here, other than to note the convenience that case expressions offer. Indeed, there's one use of a case expression that is so common that it has special syntax: the {\em conditional expression}. In Haskell, conditional expressions have the familiar form: \[ \mbox{\tt if}\ e_1\ \mbox{\tt then}\ e_2\ \mbox{\tt else}\ e_3 \] which is really short-hand for: \[\ba{ll} \mbox{\tt case}\ e_1\ \mbox{\tt of} & \mbox{\tt True\ \ ->}\ e_2\\ & \mbox{\tt False\ ->}\ e_3 \ea\] {}From this expansion it should be clear that $e_1$ must have type \mbox{\tt Bool}, and $e_2$ and $e_3$ must have the same (but otherwise arbitrary) type. In other words, \mbox{\tt if}-\mbox{\tt then}-\mbox{\tt else} when viewed as a function has type \mbox{\tt Bool->a->a->a}. \subsection{Lazy Patterns} \label{tut-lazy-patterns} There is one other kind of pattern allowed in Haskell. It is called a {\em lazy pattern}, and has the form \mbox{\tt {\char'176}}$pat$. Lazy patterns are {\em irrefutable}: matching a value $v$ against \mbox{\tt {\char'176}}$pat$ always succeeds, regardless of $pat$. Operationally speaking, if an identifier in $pat$ is later ``used'' on the right-hand-side, it will be bound to that portion of the value that would result if $v$ were to successfully match $pat$, and $\bot$ otherwise. Lazy patterns are useful in contexts where infinite data structures are being defined recursively. For example, infinite lists are an excellent vehicle for writing {\em simulation} programs, and in this context the infinite lists are often called {\em streams}. Consider the simple case of simulating the interactions between a server process \mbox{\tt server} and a client process \mbox{\tt client}, where \mbox{\tt client} sends a sequence of {\em requests} to \mbox{\tt server}, and \mbox{\tt server} replies to each request with some kind of {\em response}. This situation is shown pictorially in Figure \ref{tut-client-fig}. (Note that \mbox{\tt client} also takes an initial message as argument.) %**
    \mbox{$\it %**

    Figure 2

    Using streams to simulate the message sequences, the Haskell code corresponding to this diagram is: \bprog \mbox{\tt reqs\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ client\ init\ resps}\\ \mbox{\tt resps\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ server\ reqs} \eprog These recursive equations are a direct lexical transliteration of the diagram. %*ignore \begin{figure} \begin{center} \mbox{ \epsfbox{fig2.eps}} \end{center} \caption{Client-Server Simulation} \label{tut-client-fig} \end{figure} %*endignore Let us further assume that the structure of the server and client look something like this: \bprog \mbox{\tt client\ init\ (resp:resps)\ =\ init\ :\ client\ (next\ resp)\ resps}\\ \mbox{\tt server\ \ \ \ \ \ (req:reqs)\ \ \ =\ process\ req\ :\ server\ reqs} \eprog where we assume that \mbox{\tt next} is a function that, given a response from the server, determines the next request, and \mbox{\tt process} is a function that processes a request from the client, returning an appropriate response. Unfortunately, this program has a serious problem: it will not produce any output! The problem is that \mbox{\tt client}, as used in the recursive setting of \mbox{\tt reqs} and \mbox{\tt resps}, attempts a match on the response list before it has submitted its first request! In other words, the pattern matching is being done ``too early.'' One way to fix this is to redefine \mbox{\tt client} as follows: \bprog \mbox{\tt client\ init\ resps\ \ \ \ \ \ \ \ \ =\ init\ :\ client\ (next\ (head\ resps))\ (tail\ resps)} \eprog Although workable, this solution does not read as well as that given earlier. A better solution is to use a lazy pattern: \bprog \mbox{\tt client\ init\ {\char'176}(resp:resps)\ =\ init\ :\ client\ (next\ resp)\ resps} \eprog Because lazy patterns are irrefutable, the match will immediately succeed, allowing the initial request to be ``submitted'', in turn allowing the first response to be generated; the engine is now ``primed'', and the recursion takes care of the rest. As an example of this program in action, if we define: \bprog \mbox{\tt init\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ 0}\\ \mbox{\tt next\ resp\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ resp}\\ \mbox{\tt process\ req\ \ \ \ \ \ \ \ \ \ \ \ \ =\ req+1} \eprog then we see that: \[ \mbox{\tt take\ 10\ reqs}\ \ \ \ \red\ \ \ \ \mbox{\tt [0,1,2,3,4,5,6,7,8,9]} \] As another example of the use of lazy patterns, consider the definition of Fibonacci given earlier: \bprog \mbox{\tt fib\ \ \ \ \ \ \ \ \ \ \ \ \ =\ 1\ :\ 1\ :\ [\ a+b\ |\ (a,b)\ <-\ zip\ fib\ (tail\ fib)\ ]} \eprog We might try rewriting this using an as-pattern: \bprog \mbox{\tt fib@(1:tfib)\ \ \ \ =\ 1\ :\ 1\ :\ [\ a+b\ |\ (a,b)\ <-\ zip\ fib\ tfib\ ]} \eprog This version of \mbox{\tt fib} has the (small) advantage of not using \mbox{\tt tail} on the right-hand side, since it is available in ``destructured'' form on the left-hand side as \mbox{\tt tfib}. \syn{This kind of equation is called a {\em pattern binding} because it is a top-level equation in which the entire left-hand side is a pattern; i.e.\ both \mbox{\tt fib} and \mbox{\tt tfib} become bound within the scope of the declaration.} Now, using the same reasoning as earlier, we should be led to believe that this program will not generate any output. Curiously, however, it {\em does}, and the reason is simple: in Haskell, pattern bindings are assumed to have an implicit \mbox{\tt {\char'176}} in front of them, reflecting the most common behavior expected of pattern bindings, and avoiding some anomalous situations which are beyond the scope of this tutorial. Thus we see that lazy patterns play an important role in Haskell, if only implicitly. \subsection{Lexical Scoping and Nested Forms} \label{tut-nesting} It is often desirable to create a nested scope within an expression, for the purpose of creating local bindings not seen elsewhere---i.e. some kind of ``block-structuring'' form. In Haskell there are two ways to achieve this: \paragraph*{Let Expressions.} Haskell's {\em let expressions} are useful whenever a nested set of bindings is required. As a simple example, consider: \bprog \mbox{\tt let\ y\ \ \ =\ a*b}\\ \mbox{\tt \ \ \ \ f\ x\ =\ (x+y)/y}\\ \mbox{\tt in\ f\ c\ +\ f\ d} \eprog The set of bindings created by a \mbox{\tt let} expression is {\em mutually recursive}, and pattern bindings are treated as lazy patterns (i.e. they carry an implicit \mbox{\tt {\char'176}}). The only kind of declarations permitted are {\em type signatures}, {\em function bindings}, and {\em pattern bindings}. \paragraph*{Where Clauses.} Sometimes it is convenient to scope bindings over several guarded equations, which requires a {\em where clause}: \bprog \mbox{\tt f\ x\ y\ \ |\ \ y>z\ \ \ \ \ \ \ \ \ \ \ =\ \ ...}\\ \mbox{\tt \ \ \ \ \ \ \ |\ \ y==z\ \ \ \ \ \ \ \ \ \ =\ \ ...}\\ \mbox{\tt \ \ \ \ \ \ \ |\ \ yA Gentle Introduction to Haskell: Classes %**~header \section{Type Classes and Overloading} \label{tut-type-classes} There is one final feature of Haskell's type system that sets it apart from other programming languages. The kind of polymorphism that we have talked about so far is commonly called {\em parametric} polymorphism. There is another kind called {\em ad hoc} polymorphism, better known as {\em overloading}. Here are some examples of {\em ad hoc} polymorphism: \begin{itemize} \item The literals \mbox{\tt 1}, \mbox{\tt 2}, etc. are often used to represent both fixed and arbitrary precision integers. \item Numeric operators such as \mbox{\tt +} are often defined to work on many different kinds of numbers. \item The equality operator (\mbox{\tt ==} in Haskell) usually works on numbers and many other (but not all) types. \end{itemize} Note that these overloaded behaviors are different for each type (in fact the behavior is sometimes undefined, or error), whereas in parametric polymorphism the type truly does not matter (\mbox{\tt fringe}, for example, really doesn't care what kind of elements are found in the leaves of a tree). In Haskell, {\em type classes} provide a structured way to control {\em ad hoc} polymorphism, or overloading. Let's start with a simple, but important, example: equality. There are many types for which we would like equality defined, but some for which we would not. For example, comparing the equality of functions is generally considered computationally intractable, whereas we often want to compare two lists for equality.\footnote{The kind of equality we are referring to here is ``value equality,'' and opposed to the ``pointer equality'' found, for example, with Java's \mbox{\tt ==}. Pointer equality is not referentially transparent, and thus does not sit well in a purely functional language.} To highlight the issue, consider this definition of the function \mbox{\tt elem} which tests for membership in a list: \bprog \mbox{\tt x\ `elem`\ \ []\ \ \ \ \ \ \ \ \ \ \ \ =\ False}\\ \mbox{\tt x\ `elem`\ (y:ys)\ \ \ \ \ \ \ \ \ =\ x==y\ ||\ (x\ `elem`\ ys)} \eprog \syn{For the stylistic reason we discussed in Section \ref{tut-lambda}, we have chosen to define \mbox{\tt elem} in infix form. \mbox{\tt ==} and \mbox{\tt ||} are the infix operators for equality and logical or, respectively.} \noindent Intuitively speaking, the type of \mbox{\tt elem} ``ought'' to be: \mbox{\tt a->[a]->Bool}. But this would imply that \mbox{\tt ==} has type \mbox{\tt a->a->Bool}, even though we just said that we don't expect \mbox{\tt ==} to be defined for all types. Furthermore, as we have noted earlier, even if \mbox{\tt ==} were defined on all types, comparing two lists for equality is very different from comparing two integers. In this sense, we expect \mbox{\tt ==} to be {\em overloaded} to carry on these various tasks. {\em Type classes} conveniently solve both of these problems. They allow us to declare which types are {\em instances} of which class, and to provide definitions of the overloaded {\em operations} associated with a class. For example, let's define a type class containing an equality operator: \bprog \mbox{\tt class\ Eq\ a\ where\ }\\ \mbox{\tt \ \ (==)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ a\ ->\ Bool} \eprog Here \mbox{\tt Eq} is the name of the class being defined, and \mbox{\tt ==} is the single operation in the class. This declaration may be read ``a type \mbox{\tt a} is an instance of the class \mbox{\tt Eq} if there is an (overloaded) operation \mbox{\tt ==}, of the appropriate type, defined on it.'' (Note that \mbox{\tt ==} is only defined on pairs of objects of the same type.) The constraint that a type \mbox{\tt a} must be an instance of the class \mbox{\tt Eq} is written \mbox{\tt Eq\ a}. Thus \mbox{\tt Eq\ a} is not a type expression, but rather it expresses a constraint on a type, and is called a {\em context}. Contexts are placed at the front of type expressions. For example, the effect of the above class declaration is to assign the following type to \mbox{\tt ==}: \bprog \mbox{\tt (==)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Eq\ a)\ =>\ a\ ->\ a\ ->\ Bool} \eprog This should be read, ``For every type \mbox{\tt a} that is an instance of the class \mbox{\tt Eq}, \mbox{\tt ==} has type \mbox{\tt a->a->Bool}''. This is the type that would be used for \mbox{\tt ==} in the \mbox{\tt elem} example, and indeed the constraint imposed by the context propagates to the principal type for \mbox{\tt elem}: \bprog \mbox{\tt elem\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Eq\ a)\ =>\ a\ ->\ [a]\ ->\ Bool} \eprog This is read, ``For every type \mbox{\tt a} that is an instance of the class \mbox{\tt Eq}, \mbox{\tt elem} has type \mbox{\tt a->[a]->Bool}''. This is just what we want---it expresses the fact that \mbox{\tt elem} is not defined on all types, just those for which we know how to compare elements for equality. So far so good. But how do we specify which types are instances of the class \mbox{\tt Eq}, and the actual behavior of \mbox{\tt ==} on each of those types? This is done with an {\em instance declaration}. For example: \bprog \mbox{\tt instance\ Eq\ Integer\ where\ }\\ \mbox{\tt \ \ x\ ==\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ `integerEq`\ y} \eprog The definition of \mbox{\tt ==} is called a {\em method}. The function \mbox{\tt integerEq} happens to be the primitive function that compares integers for equality, but in general any valid expression is allowed on the right-hand side, just as for any other function definition. The overall declaration is essentially saying: ``The type \mbox{\tt Integer} is an instance of the class \mbox{\tt Eq}, and here is the definition of the method corresponding to the operation \mbox{\tt ==}.'' Given this declaration, we can now compare fixed precision integers for equality using \mbox{\tt ==}. Similarly: \bprog \mbox{\tt instance\ Eq\ Float\ where}\\ \mbox{\tt \ \ x\ ==\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ `floatEq`\ y} \eprog allows us to compare floating point numbers using \mbox{\tt ==}. Recursive types such as \mbox{\tt Tree} defined earlier can also be handled: \bprog \mbox{\tt instance\ (Eq\ a)\ =>\ Eq\ (Tree\ a)\ where\ }\\ \mbox{\tt \ \ Leaf\ a\ \ \ \ \ \ \ \ \ ==\ Leaf\ b\ \ \ \ \ \ \ \ \ \ =\ \ a\ ==\ b}\\ \mbox{\tt \ \ (Branch\ l1\ r1)\ ==\ (Branch\ l2\ r2)\ \ =\ \ (l1==l2)\ {\char'46}{\char'46}\ (r1==r2)}\\ \mbox{\tt \ \ {\char'137}\ \ \ \ \ \ \ \ \ \ \ \ \ \ ==\ {\char'137}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ False} \eprog Note the context \mbox{\tt Eq\ a} in the first line---this is necessary because the elements in the leaves (of type \mbox{\tt a}) are compared for equality in the second line. The additional constraint is essentially saying that we can compare trees of \mbox{\tt a}'s for equality as long as we know how to compare \mbox{\tt a}'s for equality. If the context were omitted from the instance declaration, a static type error would result. The Haskell Report, especially the Prelude, contains a wealth of useful examples of type classes. Indeed, a class \mbox{\tt Eq} is defined that is slightly larger than the one defined earlier: \bprog \mbox{\tt class\ \ Eq\ a\ \ where}\\ \mbox{\tt \ \ (==),\ (/=)\ \ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ a\ ->\ Bool}\\ \mbox{\tt \ \ x\ /=\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ not\ (x\ ==\ y)} \eprog This is an example of a class with two operations, one for equality, the other for inequality. It also demonstrates the use of a {\em default method}, in this case for the inequality operation \mbox{\tt /=}. If a method for a particular operation is omitted in an instance declaration, then the default one defined in the class declaration, if it exists, is used instead. For example, the three instances of \mbox{\tt Eq} defined earlier will work perfectly well with the above class declaration, yielding just the right definition of inequality that we want: the logical negation of equality. Haskell also supports a notion of {\em class extension}. For example, we may wish to define a class \mbox{\tt Ord} which {\em inherits} all of the operations in \mbox{\tt Eq}, but in addition has a set of comparison operations and minimum and maximum functions: \bprog \mbox{\tt class\ \ (Eq\ a)\ =>\ Ord\ a\ \ where}\\ \mbox{\tt \ \ (<),\ (<=),\ (>=),\ (>)\ \ ::\ a\ ->\ a\ ->\ Bool}\\ \mbox{\tt \ \ max,\ min\ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ a\ ->\ a} \eprog Note the context in the \mbox{\tt class} declaration. We say that \mbox{\tt Eq} is a {\em superclass} of \mbox{\tt Ord} (conversely, \mbox{\tt Ord} is a {\em subclass} of \mbox{\tt Eq}), and any type which is an instance of \mbox{\tt Ord} must also be an instance of \mbox{\tt Eq}. (In the next Section we give a fuller definition of \mbox{\tt Ord} taken from the Prelude.) One benefit of such class inclusions is shorter contexts: a type expression for a function that uses operations from both the \mbox{\tt Eq} and \mbox{\tt Ord} classes can use the context \mbox{\tt (Ord\ a)}, rather than \mbox{\tt (Eq\ a,\ Ord\ a)}, since \mbox{\tt Ord} ``implies'' \mbox{\tt Eq}. More importantly, methods for subclass operations can assume the existence of methods for superclass operations. For example, the \mbox{\tt Ord} declaration in the Standard Prelude contains this default method for \mbox{\tt (<)}: \bprog \mbox{\tt \ \ \ \ x\ <\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ <=\ y\ {\char'46}{\char'46}\ x\ /=\ y} \eprog As an example of the use of \mbox{\tt Ord}, the principal typing of \mbox{\tt quicksort} defined in Section \ref{tut-list-comps} is: \bprog \mbox{\tt quicksort\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ \ (Ord\ a)\ =>\ [a]\ ->\ [a]} \eprog In other words, \mbox{\tt quicksort} only operates on lists of values of ordered types. This typing for \mbox{\tt quicksort} arises because of the use of the comparison operators \mbox{\tt <} and \mbox{\tt >=} in its definition. Haskell also permits {\em multiple inheritance}, since classes may have more than one superclass. For example, the declaration \bprog \mbox{\tt class\ (Eq\ a,\ Show\ a)\ =>\ C\ a\ where\ ...} \eprog creates a class \mbox{\tt C} which inherits operations from both \mbox{\tt Eq} and \mbox{\tt Show}. Class methods are treated as top level declarations in Haskell. They share the same namespace as ordinary variables; a name cannot be used to denote both a class method and a variable or methods in different classes. Contexts are also allowed in \mbox{\tt data} declarations; see \see{datatype-decls}. Class methods may have additional class constraints on any type variable except the one defining the current class. For example, in this class: \bprog \mbox{\tt class\ C\ a\ where}\\ \mbox{\tt \ \ m\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Show\ b\ =>\ a\ ->\ b} \eprog the method \mbox{\tt m} requires that type \mbox{\tt b} is in class \mbox{\tt Show}. However, the method \mbox{\tt m} could not place any additional class constraints on type \mbox{\tt a}. These would instead have to be part of the context in the class declaration. So far, we have been using ``first-order'' types. For example, the type constructor \mbox{\tt Tree} has so far always been paired with an argument, as in \mbox{\tt Tree\ Integer} (a tree containing \mbox{\tt Integer} values) or \mbox{\tt Tree\ a} (representing the family of trees containing \mbox{\tt a} values). But \mbox{\tt Tree} by itself is a type constructor, and as such takes a type as an argument and returns a type as a result. There are no values in Haskell that have this type, but such ``higher-order'' types can be used in \mbox{\tt class} declarations. To begin, consider the following \mbox{\tt Functor} class (taken from the Prelude): \bprog \mbox{\tt class\ Functor\ f\ where}\\ \mbox{\tt \ \ fmap\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (a\ ->\ b)\ ->\ f\ a\ ->\ f\ b} \eprog The \mbox{\tt fmap} function generalizes the \mbox{\tt map} function used previously. Note that the type variable \mbox{\tt f} is applied to other types in \mbox{\tt f\ a} and \mbox{\tt f\ b}. Thus we would expect it to be bound to a type such as \mbox{\tt Tree} which can be applied to an argument. An instance of \mbox{\tt Functor} for type \mbox{\tt Tree} would be: \bprog \mbox{\tt instance\ Functor\ Tree\ where}\\ \mbox{\tt \ \ fmap\ f\ (Leaf\ x)\ \ \ \ \ \ \ =\ Leaf\ \ \ (f\ x)}\\ \mbox{\tt \ \ fmap\ f\ (Branch\ t1\ t2)\ =\ Branch\ (fmap\ f\ t1)\ (fmap\ f\ t2)} \eprog This instance declaration declares that \mbox{\tt Tree}, rather than \mbox{\tt Tree\ a}, is an instance of \mbox{\tt Functor}. This capability is quite useful, and here demonstrates the ability to describe generic ``container'' types, allowing functions such as \mbox{\tt fmap} to work uniformly over arbitrary trees, lists, and other data types. \syn{Type applications are written in the same manner as function applications. The type \mbox{\tt T\ a\ b} is parsed as \mbox{\tt (T\ a)\ b}. Types such as tuples which use special syntax can be written in an alternative style which allows currying. For functions, \mbox{\tt (->)} is a type constructor; the types \mbox{\tt f\ ->\ g} and \mbox{\tt (->)\ f\ g} are the same. Similarly, the types \mbox{\tt [a]} and \mbox{\tt []\ a} are the same. For tuples, the type constructors (as well as the data constructors) are \mbox{\tt (,)}, \mbox{\tt (,,)}, and so on.} As we know, the type system detects typing errors in expressions. But what about errors due to malformed type expressions? The expression \mbox{\tt (+)\ 1\ 2\ 3} results in a type error since \mbox{\tt (+)} takes only two arguments. Similarly, the type \mbox{\tt Tree\ Int\ Int} should produce some sort of an error since the \mbox{\tt Tree} type takes only a single argument. So, how does Haskell detect malformed type expressions? The answer is a second type system which ensures the correctness of types! Each type has an associated \mbox{$\it kind$} which ensures that the type is used correctly. Type expressions are classified into different {\em kinds} which take one of two possible forms: \begin{itemize} \item The symbol $\ast$ represents the kind of type associated with concrete data objects. That is, if the value \mbox{$\it v$} has type \mbox{$\it t$}, the kind of \mbox{$\it v$} must be $\ast$. \item If $\kappa_1$ and $\kappa_2$ are kinds, then $\kappa_1\rightarrow\kappa_2$ is the kind of types that take a type of kind $\kappa_1$ and return a type of kind $\kappa_2$. \end{itemize} The type constructor \mbox{\tt Tree} has the kind $\ast\rightarrow\ast$; the type \mbox{\tt Tree\ Int} has the kind $\ast$. Members of the \mbox{\tt Functor} class must all have the kind $\ast\rightarrow\ast$; a kinding error would result from an declaration such as \bprog \mbox{\tt instance\ Functor\ Integer\ where\ ...} \eprog since \mbox{\tt Integer} has the kind $\ast$. Kinds do not appear directly in Haskell programs. The compiler infers kinds before doing type checking without any need for `kind declarations'. Kinds stay in the background of a Haskell program except when an erroneous type signature leads to a kind error. Kinds are simple enough that compilers should be able to provide descriptive error messages when kind conflicts occur. See \see{type-syntax} and \see{kindinference} for more information about kinds. \paragraph*{A Different Perspective.} Before going on to further examples of the use of type classes, it is worth pointing out two other views of Haskell's type classes. The first is by analogy with object-oriented programming (OOP). In the following general statement about OOP, simply substituting {\em type class} for {\em class}, and {\em type} for {\em object}, yields a valid summary of Haskell's type class mechanism: ``{\em Classes} capture common sets of operations. A particular {\em object} may be an instance of a {\em class}, and will have a method corresponding to each operation. {\em Classes} may be arranged hierarchically, forming notions of super{\em classes} and sub{\em classes}, and permitting inheritance of operations/methods. A default method may also be associated with an operation.'' In contrast to OOP, it should be clear that types are not objects, and in particular there is no notion of an object's or type's internal mutable state. An advantage over some OOP languages is that methods in Haskell are completely type-safe: any attempt to apply a method to a value whose type is not in the required class will be detected at compile time instead of at runtime. In other words, methods are not ``looked up'' at runtime but are simply passed as higher-order functions. A different perspective can be gotten by considering the relationship between parametric and {\em ad hoc} polymorphism. We have shown how parametric polymorphism is useful in defining families of types by universally quantifying over all types. Sometimes, however, that universal quantification is too broad---we wish to quantify over some smaller set of types, such as those types whose elements can be compared for equality. Type classes can be seen as providing a structured way to do just this. Indeed, we can think of parametric polymorphism as a kind of overloading too! It's just that the overloading occurs implicitly over all types instead of a constrained set of types (i.e.~a type class). \paragraph*{Comparison to Other Languages.} The classes used by Haskell are similar to those used in other object-oriented languages such as C++ and Java. However, there are some significant differences: \begin{itemize} \item Haskell separates the definition of a type from the definition of the methods associated with that type. A class in C++ or Java usually defines both a data structure (the member variables) and the functions associated with the structure (the methods). In Haskell, these definitions are separated. \item The class methods defined by a Haskell class correspond to virtual functions in a C++ class. Each instance of a class provides its own definition for each method; class defaults correspond to default definitions for a virtual function in the base class. \item Haskell classes are roughly similar to a Java interface. Like an interface declaration, a Haskell class declaration defines a protocol for using an object rather than defining an object itself. \item Haskell does not support the C++ overloading style in which functions with different types share a common name. \item The type of a Haskell object cannot be implicitly coerced; there is no universal base class such as \mbox{\tt Object} which values can be projected into or out of. \item C++ and Java attach identifying information (such as a VTable) to the runtime representation of an object. In Haskell, such information is attached logically instead of physically to values, through the type system. \item There is no access control (such as public or private class constituents) built into the Haskell class system. Instead, the module system must be used to hide or reveal components of a class. \end{itemize} %**~footer haskell-98-tutorial-sources/moretypes.tex0100644000106400000620000002760207116002315017155 0ustar jcpftp%**A Gentle Introduction to Haskell: Types, Again %**~header \section{Types, Again} Here we examine some of the more advanced aspects of type declarations. \subsection{The Newtype Declaration} A common programming practice is to define a type whose representation is identical to an existing one but which has a separate identity in the type system. In Haskell, the \mbox{\tt newtype} declaration creates a new type from an existing one. For example, natural numbers can be represented by the type \mbox{\tt Integer} using the following declaration: \bprog \mbox{\tt newtype\ Natural\ =\ MakeNatural\ Integer} \eprog This creates an entirely new type, \mbox{\tt Natural}, whose only constructor contains a single \mbox{\tt Integer}. The constructor \mbox{\tt MakeNatural} converts between an \mbox{\tt Natural} and an \mbox{\tt Integer}: \bprog \mbox{\tt toNatural\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Integer\ ->\ Natural}\\ \mbox{\tt toNatural\ x\ |\ x\ <\ 0\ \ \ \ \ =\ error\ "Can't\ create\ negative\ naturals!"\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ |\ otherwise\ =\ MakeNatural\ x}\\ \mbox{\tt }\\[-8pt] \mbox{\tt fromNatural\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Natural\ ->\ Integer}\\ \mbox{\tt fromNatural\ (MakeNatural\ i)\ =\ i} \eprog The following instance declaration admits \mbox{\tt Natural} to the \mbox{\tt Num} class: \bprog \mbox{\tt instance\ Num\ Natural\ where}\\ \mbox{\tt \ \ \ \ fromInteger\ \ \ \ \ \ \ \ \ =\ toNatural}\\ \mbox{\tt \ \ \ \ x\ +\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ toNatural\ (fromNatural\ x\ +\ fromNatural\ y)}\\ \mbox{\tt \ \ \ \ x\ -\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ let\ r\ =\ fromNatural\ x\ -\ fromNatural\ y\ in}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ r\ <\ 0\ then\ error\ "Unnatural\ subtraction"}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ toNatural\ r}\\ \mbox{\tt \ \ \ \ x\ *\ y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ toNatural\ (fromNatural\ x\ *\ fromNatural\ y)} \eprog Without this declaration, \mbox{\tt Natural} would not be in \mbox{\tt Num}. Instances declared for the old type do not carry over to the new one. Indeed, the whole purpose of this type is to introduce a different \mbox{\tt Num} instance. This would not be possible if \mbox{\tt Natural} were defined as a type synonym of \mbox{\tt Integer}. All of this works using a \mbox{\tt data} declaration instead of a \mbox{\tt newtype} declaration. However, the \mbox{\tt data} declaration incurs extra overhead in the representation of \mbox{\tt Natural} values. The use of \mbox{\tt newtype} avoids the extra level of indirection (caused by laziness) that the \mbox{\tt data} declaration would introduce. See section \ref{datatype-renaming} of the report for a more discussion of the relation between \mbox{\tt newtype}, \mbox{\tt data}, and \mbox{\tt type} declarations. \syn{Except for the keyword, the \mbox{\tt newtype} declaration uses the same syntax as a \mbox{\tt data} declaration with a single constructor containing a single field. This is appropriate since types defined using \mbox{\tt newtype} are nearly identical to those created by an ordinary \mbox{\tt data} declaration.} \subsection{Field Labels} The fields within a Haskell data type can be accessed either positionally or by name using \mbox{$\it field\ labels$}. Consider a data type for a two-dimensional point: \bprog \mbox{\tt data\ Point\ =\ Pt\ Float\ Float} \eprog The two components of a \mbox{\tt Point} are the first and second arguments to the constructor \mbox{\tt Pt}. A function such as \bprog \mbox{\tt pointx\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Point\ ->\ Float}\\ \mbox{\tt pointx\ (Pt\ x\ {\char'137})\ \ \ \ \ \ \ \ \ =\ \ x} \eprog may be used to refer to the first component of a point in a more descriptive way, but, for large structures, it becomes tedious to create such functions by hand. Constructors in a \mbox{\tt data} declaration may be declared with associated \mbox{$\it field\ names$}, enclosed in braces. These field names identify the components of constructor by name rather than by position. This is an alternative way to define \mbox{\tt Point}: \bprog \mbox{\tt data\ Point\ =\ Pt\ {\char'173}pointx,\ pointy\ ::\ Float{\char'175}} \eprog This data type is identical to the earlier definition of \mbox{\tt Point}. The constructor \mbox{\tt Pt} is the same in both cases. However, this declaration also defines two field names, \mbox{\tt pointx} and \mbox{\tt pointy}. These field names can be used as \mbox{$\it selector\ functions$} to extract a component from a structure. In this example, the selectors are: \bprog \mbox{\tt pointx\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ \ \ Point\ ->\ Float\ }\\ \mbox{\tt pointy\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ \ \ Point\ ->\ Float\ } \eprog This is a function using these selectors: \bprog \mbox{\tt absPoint\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Point\ ->\ Float}\\ \mbox{\tt absPoint\ p\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ sqrt\ (pointx\ p\ *\ pointx\ p\ +\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ pointy\ p\ *\ pointy\ p)} \eprog Field labels can also be used to construct new values. The expression \mbox{\tt Pt\ {\char'173}pointx=1,\ pointy=2{\char'175}} is identical to \mbox{\tt Pt\ 1\ 2}. The use of field names in the declaration of a data constructor does not preclude the positional style of field access; both \mbox{\tt Pt\ {\char'173}pointx=1,\ pointy=2{\char'175}} and \mbox{\tt Pt\ 1\ 2} are allowed. When constructing a value using field names, some fields may be omitted; these absent fields are undefined. Pattern matching using field names uses a similar syntax for the constructor \mbox{\tt Pt}: \bprog \mbox{\tt absPoint\ (Pt\ {\char'173}pointx\ =\ x,\ pointy\ =\ y{\char'175})\ =\ sqrt\ (x*x\ +\ y*y)\ } \eprog An update function uses field values in an existing structure to fill in components of a new structure. If \mbox{\tt p} is a \mbox{\tt Point}, then \mbox{\tt p\ {\char'173}pointx=2{\char'175}} is a point with the same \mbox{\tt pointy} as \mbox{\tt p} but with \mbox{\tt pointx} replaced by \mbox{\tt 2}. This is not a destructive update: the update function merely creates a new copy of the object, filling in the specified fields with new values. \syn{The braces used in conjunction with field labels are somewhat special: Haskell syntax usually allows braces to be omitted using the \mbox{$\it layout\ rule$} (described in Section \ref{tut-layout}). However, the braces associated with field names must be explicit.} %Within the braces used to name the fields of a structure, {\em %punning}---using the same word in two different ways---can be used to %abbreviate bindings which associate a field name with a local variable %of the same name. That is, \mbox{\tt {\char'173}pointx{\char'175}} abbreviates \mbox{\tt {\char'173}pointx\ =\ pointx{\char'175}} %in a field list. Thus, the \mbox{\tt abs} function could also be written %\bprog % %abs (Pt {pointx, pointy}) = sqrt (pointx*pointx + pointy*pointy) % %\eprog Field names are not restricted to types with a single constructor (commonly called `record' types). In a type with multiple constructors, selection or update operations using field names may fail at runtime. This is similar to the behavior of the \mbox{\tt head} function when applied to an empty list. Field labels share the top level namespace with ordinary variables and class methods. A field name cannot be used in more than one data type in scope. However, within a data type, the same field name can be used in more than one of the constructors so long as it has the same typing in all cases. For example, in this data type \bprog \mbox{\tt data\ T\ =\ C1\ {\char'173}f\ ::\ Int,\ g\ ::\ Float{\char'175}}\\ \mbox{\tt \ \ \ \ \ \ \ |\ C2\ {\char'173}f\ ::\ Int,\ h\ ::\ Bool{\char'175}} \eprog the field name \mbox{\tt f} applies to both constructors in \mbox{\tt T}. Thus if \mbox{\tt x} is of type \mbox{\tt T}, then \mbox{\tt x\ {\char'173}f=5{\char'175}} will work for values created by either of the constructors in \mbox{\tt T}. Field names does not change the basic nature of an algebraic data type; they are simply a convenient syntax for accessing the components of a data structure by name rather than by position. They make constructors with many components more manageable since fields can be added or removed without changing every reference to the constructor. For full details of field labels and their semantics, see Section~\see{field-labels}. \subsection{Strict Data Constructors} \label{tut-strict-flag} Data structures in Haskell are generally \mbox{$\it lazy$}: the components are not evaluated until needed. This permits structures that contain elements which, if evaluated, would lead to an error or fail to terminate. Lazy data structures enhance the expressiveness of Haskell and are an essential aspect of the Haskell programming style. Internally, each field of a lazy data object is wrapped up in a structure commonly referred to as a \mbox{$\it thunk$} that encapsulates the computation defining the field value. This thunk is not entered until the value is needed; thunks which contain errors (\mbox{$\it \bot$}) do not affect other elements of a data structure. For example, the tuple \mbox{\tt ('a',}\mbox{$\it \bot$}\mbox{\tt )} is a perfectly legal Haskell value. The \mbox{\tt 'a'} may be used without disturbing the other component of the tuple. Most programming languages are \mbox{$\it strict$} instead of lazy: that is, all components of a data structure are reduced to values before being placed in the structure. There are a number of overheads associated with thunks: they take time to construct and evaluate, they occupy space in the heap, and they cause the garbage collector to retain other structures needed for the evaluation of the thunk. To avoid these overheads, {\em strictness flags} in \mbox{\tt data} declarations allow specific fields of a constructor to be evaluated immediately, selectively suppressing laziness. A field marked by \mbox{$\it \makebox{\tt !}$} in a \mbox{\tt data} declaration is evaluated when the structure is created instead of delayed in a thunk. There are a number of situations where it may be appropriate to use strictness flags: \begin{itemize} \item Structure components that are sure to be evaluated at some point during program execution. \item Structure components that are simple to evaluate and never cause errors. \item Types in which partially undefined values are not meaningful. \end{itemize} For example, the complex number library defines the \mbox{\tt Complex} type as: \bprog \mbox{\tt data\ RealFloat\ a\ =>\ Complex\ a\ =\ !a\ :+\ !a} \eprog \syn{note the infix definition of the constructor \mbox{\tt :+}.} This definition marks the two components, the real and imaginary parts, of the complex number as being strict. This is a more compact representation of complex numbers but this comes at the expense of making a complex number with an undefined component, \mbox{\tt 1\ :+\ } \mbox{$\it \bot$} for example, totally undefined (\mbox{$\it \bot$}). As there is no real need for partially defined complex numbers, it makes sense to use strictness flags to achieve a more efficient representation. Strictness flags may be used to address memory leaks: structures retained by the garbage collector but no longer necessary for computation. The strictness flag, \mbox{\tt !}, can only appear in \mbox{\tt data} declarations. It cannot be used in other type signatures or in any other type definitions. There is no corresponding way to mark function arguments as being strict, although the same effect can be obtained using the \mbox{\tt seq} or \mbox{\tt !{\char'44}} functions. See ~\see{strictness-flags} for further details. It is difficult to present exact guidelines for the use of strictness flags. They should be used with caution: laziness is one of the fundamental properties of Haskell and adding strictness flags may lead to hard to find infinite loops or have other unexpected consequences. %**~footer haskell-98-tutorial-sources/stdclasses.tex0100644000106400000620000005041307116002315017272 0ustar jcpftp%**A Gentle Introduction to Haskell: Standard Classes %**~header \section{Standard Haskell Classes} In this section we introduce the predefined standard type classes in Haskell. We have simplified these classes somewhat by omitting some of the less interesting methods in these classes; the Haskell report contains a more complete description. Also, some of the standard classes are part of the standard Haskell libraries; these are described in the Haskell Library Report. \subsection{Equality and Ordered Classes} The classes \mbox{\tt Eq} and \mbox{\tt Ord} have already been discussed. The definition of \mbox{\tt Ord} in the Prelude is somewhat more complex than the simplified version of \mbox{\tt Ord} presented earlier. In particular, note the \mbox{\tt compare} method: \bprog \mbox{\tt data\ Ordering\ \ \ \ \ \ \ \ \ \ \ =\ \ EQ\ |\ LT\ |\ GT\ }\\ \mbox{\tt compare\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Ord\ a\ =>\ a\ ->\ a\ ->\ Ordering} \eprog The \mbox{\tt compare} method is sufficient to define all other methods (via defaults) in this class and is the best way to create \mbox{\tt Ord} instances. \subsection{The Enumeration Class} \label{tut-enum-classes} Class \mbox{\tt Enum} has a set of operations that underlie the syntactic sugar of arithmetic sequences; for example, the arithmetic sequence expression \mbox{\tt [1,3..]} stands for \mbox{\tt enumFromThen\ 1\ 3} (see \see{arithmetic-sequences} for the formal translation). We can now see that arithmetic sequence expressions can be used to generate lists of any type that is an instance of \mbox{\tt Enum}. This includes not only most numeric types, but also \mbox{\tt Char}, so that, for instance, \mbox{\tt ['a'..'z']} denotes the list of lower-case letters in alphabetical order. Furthermore, user-defined enumerated types like \mbox{\tt Color} can easily be given \mbox{\tt Enum} instance declarations. If so: \[ \mbox{\tt [Red\ ..\ Violet]}\ \ \ \ \red\ \ \ \ \mbox{\tt [Red,\ Green,\ Blue,\ Indigo,\ Violet]} \] Note that such a sequence is {\em arithmetic} in the sense that the increment between values is constant, even though the values are not numbers. Most types in \mbox{\tt Enum} can be mapped onto fixed precision integers; for these, the \mbox{\tt fromEnum} and \mbox{\tt toEnum} convert between \mbox{\tt Int} and a type in \mbox{\tt Enum}. \subsection{The Read and Show Classes} \label{tut-text-class} The instances of class \mbox{\tt Show} are those types that can be converted to character strings (typically for I/O). The class \mbox{\tt Read} provides operations for parsing character strings to obtain the values they may represent. The simplest function in the class \mbox{\tt Show} is \mbox{\tt show}: \bprog \mbox{\tt show\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Show\ a)\ =>\ a\ ->\ String} \eprog Naturally enough, \mbox{\tt show} takes any value of an appropriate type and returns its representation as a character string (list of characters), as in \mbox{\tt show\ (2+2)}, which results in \mbox{\tt "4"}. This is fine as far as it goes, but we typically need to produce more complex strings that may have the representations of many values in them, as in \bprog \mbox{\tt "The\ sum\ of\ "\ ++\ show\ x\ ++\ "\ and\ "\ ++\ show\ y\ ++\ "\ is\ "\ ++\ show\ (x+y)\ ++\ "."} \eprog and after a while, all that concatenation gets to be a bit inefficient. Specifically, let's consider a function to represent the binary trees of Section \ref{tut-recursive-types} as a string, with suitable markings to show the nesting of subtrees and the separation of left and right branches (provided the element type is representable as a string): \bprog \mbox{\tt showTree\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Show\ a)\ =>\ Tree\ a\ ->\ String}\\ \mbox{\tt showTree\ (Leaf\ x)\ \ \ \ \ \ \ =\ \ show\ x}\\ \mbox{\tt showTree\ (Branch\ l\ r)\ \ \ =\ \ "<"\ ++\ showTree\ l\ ++\ "|"\ ++\ showTree\ r\ ++\ ">"} \eprog Because \mbox{\tt (++)} has time complexity linear in the length of its left argument, \mbox{\tt showTree} is potentially quadratic in the size of the tree. To restore linear complexity, the function \mbox{\tt shows} is provided: \bprog \mbox{\tt shows\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Show\ a)\ =>\ a\ ->\ String\ ->\ String} \eprog \mbox{\tt shows} takes a printable value and a string and returns that string with the value's representation concatenated at the front. The second argument serves as a sort of string accumulator, and \mbox{\tt show} can now be defined as \mbox{\tt shows} with the null accumulator. This is the default definition of \mbox{\tt show} in the \mbox{\tt Show} class definition: \bprog \mbox{\tt show\ x\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ shows\ x\ ""} \eprog We can use \mbox{\tt shows} to define a more efficient version of \mbox{\tt showTree}, which also has a string accumulator argument: \bprog \mbox{\tt showsTree\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Show\ a)\ =>\ Tree\ a\ ->\ String\ ->\ String}\\ \mbox{\tt showsTree\ (Leaf\ x)\ s\ \ \ \ =\ \ shows\ x\ s}\\ \mbox{\tt showsTree\ (Branch\ l\ r)\ s=\ \ '<'\ :\ showsTree\ l\ ('|'\ :\ showsTree\ r\ ('>'\ :\ s))} \eprog This solves our efficiency problem (\mbox{\tt showsTree} has linear complexity), but the presentation of this function (and others like it) can be improved. First, let's create a type synonym: \bprog \mbox{\tt type\ ShowS\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ String\ ->\ String} \eprog This is the type of a function that returns a string representation of something followed by an accumulator string. Second, we can avoid carrying accumulators around, and also avoid amassing parentheses at the right end of long constructions, by using functional composition: \bprog \mbox{\tt showsTree\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Show\ a)\ =>\ Tree\ a\ ->\ ShowS}\\ \mbox{\tt showsTree\ (Leaf\ x)\ \ \ \ \ \ =\ \ shows\ x}\\ \mbox{\tt showsTree\ (Branch\ l\ r)\ \ =\ \ ('<':)\ .\ showsTree\ l\ .\ ('|':)\ .\ showsTree\ r\ .\ ('>':)} \eprog Something more important than just tidying up the code has come about by this transformation: we have raised the presentation from an {\em object level} (in this case, strings) to a {\em function level.} We can think of the typing as saying that \mbox{\tt showsTree} maps a tree into a {\em showing function}. Functions like \mbox{\tt ('<'\ :)} or \mbox{\tt ("a\ string"\ ++)} are primitive showing functions, and we build up more complex functions by function composition. Now that we can turn trees into strings, let's turn to the inverse problem. The basic idea is a parser for a type \mbox{\tt a}, which is a function that takes a string and returns a list of \mbox{\tt (a,\ String)} pairs~\cite{wadler:list-of-successes}. The Prelude provides a type synonym for such functions: \bprog \mbox{\tt type\ ReadS\ a\ \ \ \ \ \ \ \ \ \ \ \ =\ \ String\ ->\ [(a,String)]} \eprog Normally, a parser returns a singleton list, containing a value of type \mbox{\tt a} that was read from the input string and the remaining string that follows what was parsed. If no parse was possible, however, the result is the empty list, and if there is more than one possible parse (an ambiguity), the resulting list contains more than one pair. The standard function \mbox{\tt reads} is a parser for any instance of \mbox{\tt Read}: \bprog \mbox{\tt reads\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Read\ a)\ =>\ ReadS\ a} \eprog We can use this function to define a parsing function for the string representation of binary trees produced by \mbox{\tt showsTree}. List comprehensions give us a convenient idiom for constructing such parsers:\footnote{An even more elegant approach to parsing uses monads and parser combinators. These are part of a standard parsing library distributed with most Haskell systems.} \bprog \mbox{\tt readsTree\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Read\ a)\ =>\ ReadS\ (Tree\ a)}\\ \mbox{\tt readsTree\ ('<':s)\ \ \ \ \ \ \ =\ \ [(Branch\ l\ r,\ u)\ |\ (l,\ '|':t)\ <-\ readsTree\ s,}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (r,\ '>':u)\ <-\ readsTree\ t\ ]}\\ \mbox{\tt readsTree\ s\ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ [(Leaf\ x,\ t)\ \ \ \ \ |\ (x,t)\ \ \ \ \ \ <-\ reads\ s]} \eprog Let's take a moment to examine this function definition in detail. There are two main cases to consider: If the first character of the string to be parsed is \mbox{\tt '<'}, we should have the representation of a branch; otherwise, we have a leaf. In the first case, calling the rest of the input string following the opening angle bracket \mbox{\tt s}, any possible parse must be a tree \mbox{\tt Branch\ l\ r} with remaining string \mbox{\tt u}, subject to the following conditions: \begin{enumerate} \item The tree \mbox{\tt l} can be parsed from the beginning of the string \mbox{\tt s}. \item The string remaining (following the representation of \mbox{\tt l}) begins with \mbox{\tt '|'}. Call the tail of this string \mbox{\tt t}. \item The tree \mbox{\tt r} can be parsed from the beginning of \mbox{\tt t}. \item The string remaining from that parse begins with \mbox{\tt '>'}, and \mbox{\tt u} is the tail. \end{enumerate} Notice the expressive power we get from the combination of pattern matching with list comprehension: the form of a resulting parse is given by the main expression of the list comprehension, the first two conditions above are expressed by the first generator (``\mbox{\tt (l,\ '|':t)} is drawn from the list of parses of \mbox{\tt s}''), and the remaining conditions are expressed by the second generator. The second defining equation above just says that to parse the representation of a leaf, we parse a representation of the element type of the tree and apply the constructor \mbox{\tt Leaf} to the value thus obtained. We'll accept on faith for the moment that there is a \mbox{\tt Read} (and \mbox{\tt Show}) instance of \mbox{\tt Integer} (among many other types), providing a \mbox{\tt reads} that behaves as one would expect, e.g.: \[ \mbox{\tt (reads\ "5\ golden\ rings")\ ::\ [(Integer,String)]}\ \ \ \ \red\ \ \ \ % \mbox{\tt [(5,\ "\ golden\ rings")]} \] With this understanding, the reader should verify the following evaluations: \[\ba{lcl} \mbox{\tt readsTree\ "<1|<2|3>>"}&\ \ \ \ \red\ \ \ \ & \mbox{\tt [(Branch\ (Leaf\ 1)\ (Branch\ (Leaf\ 2)\ (Leaf\ 3)),\ "")]}\\ \mbox{\tt readsTree\ "<1|2"} &\ \ \ \ \red\ \ \ \ & \mbox{\tt []} \ea\] There are a couple of shortcomings in our definition of \mbox{\tt readsTree}. One is that the parser is quite rigid, allowing no white space before or between the elements of the tree representation; the other is that the way we parse our punctuation symbols is quite different from the way we parse leaf values and subtrees, this lack of uniformity making the function definition harder to read. We can address both of these problems by using the lexical analyzer provided by the Prelude: \bprog \mbox{\tt lex\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ ReadS\ String} \eprog \mbox{\tt lex} normally returns a singleton list containing a pair of strings: the first lexeme in the input string and the remainder of the input. The lexical rules are those of Haskell programs, including comments, which \mbox{\tt lex} skips, along with whitespace. If the input string is empty or contains only whitespace and comments, \mbox{\tt lex} returns \mbox{\tt [("","")]}; if the input is not empty in this sense, but also does not begin with a valid lexeme after any leading whitespace and comments, \mbox{\tt lex} returns \mbox{\tt []}. Using the lexical analyzer, our tree parser now looks like this: \bprog \mbox{\tt readsTree\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Read\ a)\ =>\ ReadS\ (Tree\ a)}\\ \mbox{\tt readsTree\ s\ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ [(Branch\ l\ r,\ x)\ |\ ("<",\ t)\ <-\ lex\ s,}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (l,\ \ \ u)\ <-\ readsTree\ t,}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ("|",\ v)\ <-\ lex\ u,}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (r,\ \ \ w)\ <-\ readsTree\ v,}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (">",\ x)\ <-\ lex\ w\ \ \ \ \ \ \ \ \ ]}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ++}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [(Leaf\ x,\ t)\ \ \ \ \ |\ (x,\ \ \ t)\ <-\ reads\ s\ \ \ \ \ \ \ ]} \eprog We may now wish to use \mbox{\tt readsTree} and \mbox{\tt showsTree} to declare \mbox{\tt (Read\ a)\ =>\ Tree\ a} an instance of \mbox{\tt Read} and \mbox{\tt (Show\ a)\ =>\ Tree\ a} an instance of \mbox{\tt Show}. This would allow us to use the generic overloaded functions from the Prelude to parse and display trees. Moreover, we would automatically then be able to parse and display many other types containing trees as components, for example, \mbox{\tt [Tree\ Integer]}. As it turns out, \mbox{\tt readsTree} and \mbox{\tt showsTree} are of almost the right types to be \mbox{\tt Show} and \mbox{\tt Read} methods % , needing % only the addition of an extra parameter each that has do do with % parenthesization of forms with infix constructors. The \mbox{\tt showsPrec} and \mbox{\tt readsPrec} methods are parameterized versions of \mbox{\tt shows} and \mbox{\tt reads}. The extra parameter is a precedence level, used to properly parenthesize expressions containing infix constructors. For types such as \mbox{\tt Tree}, the precedence can be ignored. The \mbox{\tt Show} and \mbox{\tt Read} instances for \mbox{\tt Tree} are: \bprog \mbox{\tt instance\ Show\ a\ =>\ Show\ (Tree\ a)\ where}\\ \mbox{\tt \ \ \ \ showsPrec\ {\char'137}\ x\ =\ showsTree\ x}\\ \mbox{\tt }\\[-8pt] \mbox{\tt instance\ Read\ a\ =>\ Read\ (Tree\ a)\ where}\\ \mbox{\tt \ \ \ \ readsPrec\ {\char'137}\ s\ =\ readsTree\ s} \eprog Alternatively, the \mbox{\tt Show} instance could be defined in terms of \mbox{\tt showTree}: \bprog \mbox{\tt instance\ Show\ a\ =>\ Show\ (Tree\ a)\ where}\\ \mbox{\tt \ \ \ show\ t\ =\ showTree\ t} \eprog This, however, will be less efficient than the \mbox{\tt ShowS} version. Note that the \mbox{\tt Show} class defines default methods for both \mbox{\tt showsPrec} and \mbox{\tt show}, allowing the user to define either one of these in an instance declaration. Since these defaults are mutually recursive, an instance declaration that defines neither of these functions will loop when called. Other classes such as \mbox{\tt Num} also have these ``interlocking defaults''. We refer the interested reader to \see{derived-appendix} for details of the \mbox{\tt Read} and \mbox{\tt Show} classes. We can test the \mbox{\tt Read} and \mbox{\tt Show} instances by applying \mbox{\tt (read\ .\ show)} (which should be the identity) to some trees, where \mbox{\tt read} is a specialization of \mbox{\tt reads}: \bprog \mbox{\tt read\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Read\ a)\ =>\ String\ ->\ a} \eprog This function fails if there is not a unique parse or if the input contains anything more than a representation of one value of type \mbox{\tt a} (and possibly, comments and whitespace). \subsection{Derived Instances} \label{tut-derived-instances} Recall the \mbox{\tt Eq} instance for trees we presented in Section \ref{tut-type-classes}; such a declaration is simple---and boring---to produce: we require that the element type in the leaves be an equality type; then, two leaves are equal iff they contain equal elements, and two branches are equal iff their left and right subtrees are equal, respectively. Any other two trees are unequal: \bprog \mbox{\tt instance\ \ (Eq\ a)\ =>\ Eq\ (Tree\ a)\ \ where}\\ \mbox{\tt \ \ \ \ (Leaf\ x)\ \ \ \ \ ==\ (Leaf\ y)\ \ \ \ \ \ \ \ =\ \ x\ ==\ y}\\ \mbox{\tt \ \ \ \ (Branch\ l\ r)\ ==\ (Branch\ l'\ r')\ \ =\ \ l\ ==\ l'\ {\char'46}{\char'46}\ r\ ==\ r'}\\ \mbox{\tt \ \ \ \ {\char'137}\ \ \ \ \ \ \ \ \ \ \ \ ==\ {\char'137}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ False} \eprog Fortunately, we don't need to go through this tedium every time we need equality operators for a new type; the \mbox{\tt Eq} instance can be {\em derived automatically} from the \mbox{\tt data} declaration if we so specify: \bprog \mbox{\tt data\ \ Tree\ a\ \ \ \ \ \ \ \ \ \ \ \ =\ \ Leaf\ a\ |\ Branch\ (Tree\ a)\ (Tree\ a)\ \ deriving\ Eq} \eprog The \mbox{\tt deriving} clause implicitly produces an \mbox{\tt Eq} instance declaration just like the one in Section \ref{tut-type-classes}. Instances of \mbox{\tt Ord}, \mbox{\tt Enum}, \mbox{\tt Ix}, \mbox{\tt Read}, and \mbox{\tt Show} can also be generated by the \mbox{\tt deriving} clause. \syn{More than one class name can be specified, in which case the list of names must be parenthesized and the names separated by commas.} The derived \mbox{\tt Ord} instance for \mbox{\tt Tree} is slightly more complicated than the \mbox{\tt Eq} instance: \bprog \mbox{\tt instance\ \ (Ord\ a)\ =>\ Ord\ (Tree\ a)\ \ where}\\ \mbox{\tt \ \ \ \ (Leaf\ {\char'137})\ \ \ \ \ <=\ (Branch\ {\char'137})\ \ \ \ \ \ =\ \ True}\\ \mbox{\tt \ \ \ \ (Leaf\ x)\ \ \ \ \ <=\ (Leaf\ y)\ \ \ \ \ \ \ \ =\ \ x\ <=\ y}\\ \mbox{\tt \ \ \ \ (Branch\ {\char'137})\ \ \ <=\ (Leaf\ {\char'137})\ \ \ \ \ \ \ \ =\ \ False}\\ \mbox{\tt \ \ \ \ (Branch\ l\ r)\ <=\ (Branch\ l'\ r')\ \ =\ \ l\ ==\ l'\ {\char'46}{\char'46}\ r\ <=\ r'\ ||\ l\ <=\ l'} \eprog This specifies a {\em lexicographic} order: Constructors are ordered by the order of their appearance in the \mbox{\tt data} declaration, and the arguments of a constructor are compared from left to right. Recall that the built-in list type is semantically equivalent to an ordinary two-constructor type. In fact, this is the full declaration: \bprog \mbox{\tt data\ [a]\ \ \ \ \ \ \ \ =\ []\ |\ a\ :\ [a]\ deriving\ (Eq,\ Ord)\ \ \ \ \ --\ pseudo-code} \eprog (Lists also have \mbox{\tt Show} and \mbox{\tt Read} instances, which are not derived.) The derived \mbox{\tt Eq} and \mbox{\tt Ord} instances for lists are the usual ones; in particular, character strings, as lists of characters, are ordered as determined by the underlying \mbox{\tt Char} type, with an initial substring comparing less than a longer string; for example, \mbox{\tt "cat"\ <\ "catalog"}. In practice, \mbox{\tt Eq} and \mbox{\tt Ord} instances are almost always derived, rather than user-defined. In fact, we should provide our own definitions of equality and ordering predicates only with some trepidation, being careful to maintain the expected algebraic properties of equivalence relations and total orders. An intransitive \mbox{\tt (==)} predicate, for example, could be disastrous, confusing readers of the program and confounding manual or automatic program transformations that rely on the \mbox{\tt (==)} predicate's being an approximation to definitional equality. Nevertheless, it is sometimes necessary to provide \mbox{\tt Eq} or \mbox{\tt Ord} instances different from those that would be derived; probably the most important example is that of an abstract data type in which different concrete values may represent the same abstract value. An enumerated type can have a derived \mbox{\tt Enum} instance, and here again, the ordering is that of the constructors in the \mbox{\tt data} declaration. For example: \bprog \mbox{\tt data\ Day\ =\ Sunday\ |\ Monday\ |\ Tuesday\ |\ Wednesday}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ |\ Thursday\ |\ Friday\ |\ Saturday\ \ \ \ \ \ \ \ \ deriving\ (Enum)} \eprog Here are some simple examples using the derived instances for this type: \[\ba{lcl} \mbox{\tt [Wednesday\ ..\ Friday]} \ \ &\red&\ \ \mbox{\tt [Wednesday,\ Thursday,\ Friday]}\\ \mbox{\tt [Monday,\ Wednesday\ ..]}\ \ &\red&\ \ \mbox{\tt [Monday,\ Wednesday,\ Friday]} \ea\] Derived \mbox{\tt Read} (\mbox{\tt Show}) instances are possible for all types whose component types also have \mbox{\tt Read} (\mbox{\tt Show}) instances. (\mbox{\tt Read} and \mbox{\tt Show} instances for most of the standard types are provided by the Prelude. Some types, such as the function type \mbox{\tt (->)}, have a \mbox{\tt Show} instance but not a corresponding \mbox{\tt Read}.) The textual representation defined by a derived \mbox{\tt Show} instance is consistent with the appearance of constant Haskell expressions of the type in question. For example, if we add \mbox{\tt Show} and \mbox{\tt Read} to the \mbox{\tt deriving} clause for type \mbox{\tt Day}, above, we obtain \[ \mbox{\tt show\ [Monday\ ..\ Wednesday]}\ \ \ \ \red\ \ \ \ \mbox{\tt "[Monday,Tuesday,Wednesday]"} \] %**~footer haskell-98-tutorial-sources/monads.tex0100644000106400000620000007156207121451726016425 0ustar jcpftp%**A Gentle Introduction to Haskell: About Monads %**~header \section{About Monads} \label{tut-monads} Many newcomers to Haskell are puzzled by the concept of {\em monads}. Monads are frequently encountered in Haskell: the IO system is constructed using a monad, a special syntax for monads has been provided (\mbox{\tt do} expressions), and the standard libraries contain an entire module dedicated to monads. In this section we explore monadic programming in more detail. This section is perhaps less ``gentle'' than the others. Here we address not only the language features that involve monads but also try to reveal the bigger picture: why monads are such an important tool and how they are used. There is no single way of explaining monads that works for everyone; more explanations can be found at {\tt haskell.org}. Another good introduction to practical programming using monads is Wadler's {\em Monads for Functional Programming}~\cite{wadler:mffp}. \subsection{Monadic Classes} \label{tut-monadic-classes} The Prelude contains a number of classes defining monads are they are used in Haskell. These classes are based on the monad construct in category theory; whilst the category theoretic terminology provides the names for the monadic classes and operations, it is not necessary to delve into abstract mathematics to get an intuitive understanding of how to use the monadic classes. A monad is constructed on top of a polymorphic type such as \mbox{\tt IO}. The monad itself is defined by instance declarations associating the type with the some or all of the monadic classes, \mbox{\tt Functor}, \mbox{\tt Monad}, and \mbox{\tt MonadPlus}. None of the monadic classes are derivable. In addition to \mbox{\tt IO}, two other types in the Prelude are members of the monadic classes: lists (\mbox{\tt []}) and \mbox{\tt Maybe}. Mathematically, monads are governed by set of {\em laws} that should hold for the monadic operations. This idea of laws is not unique to monads: Haskell includes other operations that are governed, at least informally, by laws. For example, \mbox{\tt x\ /=\ y} and \mbox{\tt not\ (x\ ==\ y)} ought to be the same for any type of values being compared. However, there is no guarantee of this: both \mbox{\tt ==} and \mbox{\tt /=} are separate methods in the \mbox{\tt Eq} class and there is no way to assure that \mbox{\tt ==} and \mbox{\tt =/} are related in this manner. In the same sense, the monadic laws presented here are not enforced by Haskell, but ought be obeyed by any instances of a monadic class. The monad laws give insight into the underlying structure of monads: by examining these laws, we hope to give a feel for how monads are used. The \mbox{\tt Functor} class, already discussed in section \ref{tut-type-classes}, defines a single operation: \mbox{\tt fmap}. The map function applies an operation to the objects inside a container (polymorphic types can be thought of as containers for values of another type), returning a container of the same shape. These laws apply to \mbox{\tt fmap} in the class \mbox{\tt Functor}: \[\ba{lcl} \mbox{\tt fmap\ id}&=&\mbox{\tt id}\\ \mbox{\tt fmap\ (f\ .\ g)}&=&\mbox{\tt fmap\ f\ .\ fmap\ g}\\ \ea\] These laws ensure that the container shape is unchanged by \mbox{\tt fmap} and that the contents of the container are not re-arranged by the mapping operation. The \mbox{\tt Monad} class defines two basic operators: \mbox{\tt >>=} (bind) and \mbox{\tt return}. \bprog \mbox{\tt infixl\ 1\ \ >>,\ >>=}\\ \mbox{\tt class\ \ Monad\ m\ \ where}\\ \mbox{\tt \ \ \ \ (>>=)\ \ \ \ \ \ \ \ \ \ \ \ ::\ m\ a\ ->\ (a\ ->\ m\ b)\ ->\ m\ b}\\ \mbox{\tt \ \ \ \ (>>)\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ m\ a\ ->\ m\ b\ ->\ m\ b}\\ \mbox{\tt \ \ \ \ return\ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ m\ a}\\ \mbox{\tt \ \ \ \ fail\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ String\ ->\ m\ a}\\ \mbox{\tt }\\[-8pt] \mbox{\tt \ \ \ \ m\ >>\ k\ \ \ \ \ \ \ \ \ \ \ =\ \ m\ >>=\ {\char'134}{\char'137}\ ->\ k} \eprog The bind operations, \mbox{\tt >>} and \mbox{\tt >>=}, combine two monadic values while the \mbox{\tt return} operation injects a value into the monad (container). The signature of \mbox{\tt >>=} helps us to understand this operation: \mbox{\tt ma\ >>=\ {\char'134}v\ ->\ mb} combines a monadic value \mbox{\tt ma} containing values of type \mbox{\tt a} and a function which operates on a value \mbox{\tt v} of type \mbox{\tt a}, returning the monadic value \mbox{\tt mb}. The result is to combine \mbox{\tt ma} and \mbox{\tt mb} into a monadic value containing \mbox{\tt b}. The \mbox{\tt >>} function is used when the function does not need the value produced by the first monadic operator. The precise meaning of binding depends, of course, on the monad. For example, in the IO monad, \mbox{\tt x\ >>=\ y} performs two actions sequentially, passing the result of the first into the second. For the other built-in monads, lists and the \mbox{\tt Maybe} type, these monadic operations can be understood in terms of passing zero or more values from one calculation to the next. We will see examples of this shortly. The \mbox{\tt do} syntax provides a simple shorthand for chains of monadic operations. The essential translation of \mbox{\tt do} is captured in the following two rules: \bprog \mbox{\tt \ \ do\ e1\ ;\ e2\ \ \ \ \ \ =\ \ \ \ \ \ \ \ e1\ >>\ e2}\\ \mbox{\tt \ \ do\ p\ <-\ e1;\ e2\ \ =\ \ \ \ \ \ \ \ e1\ >>=\ {\char'134}p\ ->\ e2} \eprog When the pattern in this second form of \mbox{\tt do} is refutable, pattern match failure calls the \mbox{\tt fail} operation. This may raise an error (as in the \mbox{\tt IO} monad) or return a ``zero'' (as in the list monad). Thus the more complex translation is \bprog \mbox{\tt \ \ \ do\ p\ <-\ e1;\ e2\ \ =\ \ \ e1\ >>=\ ({\char'134}v\ ->\ case\ v\ of\ p\ ->\ e2;\ {\char'137}\ ->\ fail\ "s")\ \ \ \ } \eprog where \mbox{\tt "s"} is a string identifying the location of the \mbox{\tt do} statement for possible use in an error message. For example, in the I/O monad, an action such as \mbox{\tt 'a'\ <-\ getChar} will call \mbox{\tt fail} if the character typed is not 'a'. This, in turn, terminates the program since in the I/O monad \mbox{\tt fail} calls \mbox{\tt error}. The laws which govern \mbox{\tt >>=} and \mbox{\tt return} are: \[\ba{lcl} \mbox{\tt return\ a\ >>=\ k}&=&\mbox{\tt k\ a} \\ \mbox{\tt m\ >>=\ return}&=&\mbox{\tt m} \\ \mbox{\tt xs\ >>=\ return\ .\ f}&=&\mbox{\tt fmap\ f\ xs}\\ \mbox{\tt m\ >>=\ ({\char'134}x\ ->\ k\ x\ >>=\ h)}&=&\mbox{\tt (m\ >>=\ k)\ >>=\ h}\\ \ea\] The class \mbox{\tt MonadPlus} is used for monads that have a \mbox{$\it zero$} element and a \mbox{$\it plus$} operation: \bprog \mbox{\tt class\ \ (Monad\ m)\ =>\ MonadPlus\ m\ \ where}\\ \mbox{\tt \ \ \ \ mzero\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ m\ a}\\ \mbox{\tt \ \ \ \ mplus\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ m\ a\ ->\ m\ a\ ->\ m\ a} \eprog The zero element obeys the following laws: \[\ba{lcl} \mbox{\tt m\ >>=\ {\char'134}x\ ->\ mzero}&=&\mbox{\tt mzero}\\ \mbox{\tt mzero\ >>=\ m}&=&\mbox{\tt mzero}\\ \ea\] For lists, the zero value is \mbox{\tt []}, the empty list. The I/O monad has no zero element and is not a member of this class. The laws governing the \mbox{\tt mplus} operator are as follows: \[\ba{lcl} \mbox{\tt m\ `mplus`\ mzero}&=&\mbox{\tt m}\\ \mbox{\tt mzero\ `mplus`\ m}&=&\mbox{\tt m}\\ \ea\] The \mbox{\tt mplus} operator is ordinary list concatenation in the list monad. \subsection{Built-in Monads} Given the monadic operations and the laws that govern them, what can we build? We have already examined the I/O monad in detail so we start with the two other built-in monads. For lists, monadic binding involves joining together a set of calculations for each value in the list. When used with lists, the signature of \mbox{\tt >>=} becomes: \bprog \mbox{\tt (>>=)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ [a]\ ->\ (a\ ->\ [b])\ ->\ [b]\ } \eprog That is, given a list of \mbox{\tt a}'s and a function that maps an \mbox{\tt a} onto a list of \mbox{\tt b}'s, binding applies this function to each of the \mbox{\tt a}'s in the input and returns all of the generated \mbox{\tt b}'s concatenated into a list. The \mbox{\tt return} function creates a singleton list. These operations should already be familiar: list comprehensions can easily be expressed using the monadic operations defined for lists. These following three expressions are all different syntax for the same thing: \bprog \mbox{\tt [(x,y)\ |\ x\ <-\ [1,2,3]\ ,\ y\ <-\ [1,2,3],\ x\ /=\ y]}\\ \mbox{\tt }\\[-8pt] \mbox{\tt do\ x\ <-\ [1,2,3]}\\ \mbox{\tt \ \ \ y\ <-\ [1,2,3]}\\ \mbox{\tt \ \ \ True\ <-\ return\ (x\ /=\ y)}\\ \mbox{\tt \ \ \ return\ (x,y)}\\ \mbox{\tt }\\[-8pt] \mbox{\tt [1,2,3]\ >>=\ ({\char'134}\ x\ ->\ [1,2,3]\ >>=\ ({\char'134}y\ ->\ return\ (x/=y)\ >>=}\\ \mbox{\tt \ \ \ ({\char'134}r\ ->\ case\ r\ of\ True\ ->\ return\ (x,y)}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\char'137}\ \ \ \ ->\ fail\ "")))} \eprog This definition depends on the definition of \mbox{\tt fail} in this monad as the empty list. Essentially, each \mbox{\tt <-} is generating a set of values which is passed on into the remainder of the monadic computation. Thus \mbox{\tt x\ <-\ [1,2,3]} invokes the remainder of the monadic computation three times, once for each element of the list. The returned expression, \mbox{\tt (x,y)}, will be evaluated for all possible combinations of bindings that surround it. In this sense, the list monad can be thought of as describing functions of multi-valued arguments. For example, this function: \bprog \mbox{\tt mvLift2\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (a\ ->\ b\ ->\ c)\ ->\ [a]\ ->\ [b]\ ->\ [c]}\\ \mbox{\tt mvLift2\ f\ x\ y\ \ \ \ \ \ \ \ \ \ =\ \ do\ x'\ <-\ x}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ y'\ <-\ y}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ (f\ x'\ y')} \eprog turns an ordinary function of two arguments (\mbox{\tt f}) into a function over multiple values (lists of arguments), returning a value for each possible combination of the two input arguments. For example, \[\ba{lcl} \mbox{\tt mvLift2\ (+)\ [1,3]\ [10,20,30]} \ \ \ &\red&\ \ \ \mbox{\tt [11,21,31,13,23,33]}\\ \mbox{\tt mvLift2\ ({\char'134}a\ b->[a,b])\ "ab"\ "cd"} \ \ \ &\red&\ \ \ \mbox{\tt ["ac","ad","bc","bd"]}\\ \mbox{\tt mvLift2\ (*)\ [1,2,4]\ []}\ \ \ &\red&\ \ \ \mbox{\tt []}\\ \ea\] This function is a specialized version of the \mbox{\tt LiftM2} function in the monad library. You can think of it as transporting a function from outside the list monad, \mbox{\tt f}, into the list monad in which computations take on multiple values. The monad defined for \mbox{\tt Maybe} is similar to the list monad: the value \mbox{\tt Nothing} serves as \mbox{\tt []} and \mbox{\tt Just\ x} as \mbox{\tt [x]}. \subsection{Using Monads} Explaining the monadic operators and their associated laws doesn't really show what monads are good for. What they really provide is {\em modularity}. That is, by defining an operation monadically, we can hide underlying machinery in a way that allows new features to be incorporated into the monad transparently. Wadler's paper~\cite{wadler:mffp} is an excellent example of how monads can be used to construct modular programs. We will start with a monad taken directly from this paper, the state monad, and then build a more complex monad with a similar definition. Briefly, a state monad built around a state type \mbox{\tt S} looks like this: \bprog \mbox{\tt data\ SM\ a\ =\ SM\ (S\ ->\ (a,S))\ \ --\ The\ monadic\ type}\\ \mbox{\tt }\\[-8pt] \mbox{\tt instance\ Monad\ SM\ where}\\ \mbox{\tt \ \ --\ defines\ state\ propagation}\\ \mbox{\tt \ \ SM\ c1\ >>=\ fc2\ \ \ \ \ \ \ \ \ =\ \ SM\ ({\char'134}s0\ ->\ let\ (r,s1)\ =\ c1\ s0\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ SM\ c2\ =\ fc2\ r\ in}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ c2\ s1)}\\ \mbox{\tt \ \ return\ k\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ SM\ ({\char'134}s\ ->\ (k,s))}\\ \mbox{\tt }\\[-8pt] \mbox{\tt \ --\ extracts\ the\ state\ from\ the\ monad}\\ \mbox{\tt readSM\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ SM\ S}\\ \mbox{\tt readSM\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ SM\ ({\char'134}s\ ->\ (s,s))}\\ \mbox{\tt }\\[-8pt] \mbox{\tt \ --\ updates\ the\ state\ of\ the\ monad}\\ \mbox{\tt updateSM\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (S\ ->\ S)\ ->\ SM\ ()\ \ --\ alters\ the\ state}\\ \mbox{\tt updateSM\ f\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ SM\ ({\char'134}s\ ->\ ((),\ f\ s))\ }\\ \mbox{\tt }\\[-8pt] \mbox{\tt --\ run\ a\ computation\ in\ the\ SM\ monad}\\ \mbox{\tt runSM\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ S\ ->\ SM\ a\ ->\ (a,S)}\\ \mbox{\tt runSM\ s0\ (SM\ c)\ \ \ \ \ \ \ \ \ =\ \ c\ s0} \eprog This example defines a new type, \mbox{\tt SM}, to be a computation that implicitly carries a type \mbox{\tt S}. That is, a computation of type \mbox{\tt SM\ t} defines a value of type \mbox{\tt t} while also interacting with (reading and writing) the state of type \mbox{\tt S}. The definition of \mbox{\tt SM} is simple: it consists of functions that take a state and produce two results: a returned value (of any type) and an updated state. We can't use a type synonym here: we need a type name like \mbox{\tt SM} that can be used in instance declarations. The \mbox{\tt newtype} declaration is often used here instead of \mbox{\tt data}. This instance declaration defines the `plumbing' of the monad: how to sequence two computations and the definition of an empty computation. Sequencing (the \mbox{\tt >>=} operator) defines a computation (denoted by the constructor \mbox{\tt SM}) that passes an initial state, \mbox{\tt s0}, into \mbox{\tt c1}, then passes the value coming out of this computation, \mbox{\tt r}, to the function that returns the second computation, \mbox{\tt c2}. Finally, the state coming out of \mbox{\tt c1} is passed into \mbox{\tt c2} and the overall result is the result of \mbox{\tt c2}. The definition of \mbox{\tt return} is easier: \mbox{\tt return} doesn't change the state at all; it only serves to bring a value into the monad. While \mbox{\tt >>=} and \mbox{\tt return} are the basic monadic sequencing operations, we also need some {\em monadic primitives}. A monadic primitive is simply an operation that uses the insides of the monad abstraction and taps into the `wheels and gears' that make the monad work. For example, in the \mbox{\tt IO} monad, operators such as \mbox{\tt putChar} are primitive since they deal with the inner workings of the \mbox{\tt IO} monad. Similarly, our state monad uses two primitives: \mbox{\tt readSM} and \mbox{\tt updateSM}. Note that these depend on the inner structure of the monad - a change to the definition of the \mbox{\tt SM} type would require a change to these primitives. The definition of \mbox{\tt readSM} and \mbox{\tt updateSM} are simple: \mbox{\tt readSM} brings the state out of the monad for observation while \mbox{\tt updateSM} allows the user to alter the state in the monad. (We could also have used \mbox{\tt writeSM} as a primitive but update is often a more natural way of dealing with state). Finally, we need a function that runs computations in the monad, \mbox{\tt runSM}. This takes an initial state and a computation and yields both the returned value of the computation and the final state. Looking at the bigger picture, what we are trying to do is define an overall computation as a series of steps (functions with type \mbox{\tt SM\ a}), sequenced using \mbox{\tt >>=} and \mbox{\tt return}. These steps may interact with the state (via \mbox{\tt readSM} or \mbox{\tt updateSM}) or may ignore the state. However, the use (or non-use) of the state is hidden: we don't invoke or sequence our computations differently depending on whether or not they use \mbox{\tt S}. Rather than present any examples using this simple state monad, we proceed on to a more complex example that includes the state monad. We define a small {\em embedded language} of resource-using calculations. That is, we build a special purpose language implemented as a set of Haskell types and functions. Such languages use the basic tools of Haskell, functions and types, to build a library of operations and types specifically tailored to a domain of interest. In this example, consider a computation that requires some sort of resource. If the resource is available, computation proceeds; when the resource is unavailable, the computation suspends. We use the type \mbox{\tt R} to denote a computation using resources controlled by our monad. The definition of \mbox{\tt R} is as follows: \bprog \mbox{\tt data\ R\ a\ =\ R\ (Resource\ ->\ (Resource,\ Either\ a\ (R\ a)))} \eprog Each computation is a function from available resources to remaining resources, coupled with either a result, of type \mbox{\tt a}, or a suspended computation, of type \mbox{\tt R\ a}, capturing the work done up to the point where resources were exhausted. The \mbox{\tt Monad} instance for \mbox{\tt R} is as follows: \bprog \mbox{\tt instance\ Monad\ R\ where}\\ \mbox{\tt \ \ R\ c1\ >>=\ fc2\ \ \ \ \ \ \ \ \ \ =\ R\ ({\char'134}r\ ->\ case\ c1\ r\ of}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (r',\ Left\ v)\ \ \ \ ->\ let\ R\ c2\ =\ fc2\ v\ in}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ c2\ r'}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (r',\ Right\ pc1)\ ->\ (r',\ Right\ (pc1\ >>=\ fc2)))}\\ \mbox{\tt \ \ return\ v\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ R\ ({\char'134}r\ ->\ (r,\ (Left\ v)))} \eprog The \mbox{\tt Resource} type is used in the same manner as the state in the state monad. This definition reads as follows: to combine two `resourceful' computations, \mbox{\tt c1} and \mbox{\tt fc2} (a function producing \mbox{\tt c2}), pass the initial resources into \mbox{\tt c1}. The result will be either \begin{itemize} \item a value, \mbox{\tt v}, and remaining resources, which are used to determine the next computation (the call \mbox{\tt fc2\ v}), or \item a suspended computation, \mbox{\tt pc1}, and resources remaining at the point of suspension. \end{itemize} The suspension must take the second computation into consideration: \mbox{\tt pc1} suspends only the first computation, \mbox{\tt c1}, so we must bind \mbox{\tt c2} to this to produce a suspension of the overall computation. The definition of \mbox{\tt return} leaves the resources unchanged while moving \mbox{\tt v} into the monad. This instance declaration defines the basic structure of the monad but does not determine how resources are used. This monad could be used to control many types of resource or implement many different types of resource usage policies. We will demonstrate a very simple definition of resources as an example: we choose \mbox{\tt Resource} to be an \mbox{\tt Integer}, representing available computation steps: \bprog \mbox{\tt type\ Resource\ \ \ \ \ \ \ \ \ \ \ =\ \ Integer} \eprog This function takes a step unless no steps are available: \bprog \mbox{\tt step\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ R\ a}\\ \mbox{\tt step\ v\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ c\ where}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ c\ =\ R\ ({\char'134}r\ ->\ if\ r\ /=\ 0\ then\ (r-1,\ Left\ v)}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ (r,\ Right\ c))} \eprog The \mbox{\tt Left} and \mbox{\tt Right} constructors are part of the \mbox{\tt Either} type. This function continues computation in \mbox{\tt R} by returning \mbox{\tt v} so long as there is at least one computational step resource available. If no steps are available, the \mbox{\tt step} function suspends the current computation (this suspension is captured in \mbox{\tt c}) and passes this suspended computation back into the monad. So far, we have the tools to define a sequence of ``resourceful'' computations (the monad) and we can express a form of resource usage using \mbox{\tt step}. Finally, we need to address how computations in this monad are expressed. Consider an increment function in our monad: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ R\ Integer\ ->\ R\ Integer}\\ \mbox{\tt inc\ i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ do\ iValue\ <-\ i}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ step\ (iValue+1)} \eprog This defines increment as a single step of computation. The \mbox{\tt <-} is necessary to pull the argument value out of the monad; the type of \mbox{\tt iValue} is \mbox{\tt Integer} instead of \mbox{\tt R\ Integer}. This definition isn't particularly satisfying, though, compared to the standard definition of the increment function. Can we instead ``dress up'' existing operations like \mbox{\tt +} so that they work in our monadic world? We'll start with a set of {\tt lifting} functions. These bring existing functionality into the monad. Consider the definition of \mbox{\tt lift1} (this is slightly different from the \mbox{\tt liftM1} found in the \mbox{\tt Monad} library): \bprog \mbox{\tt lift1\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (a\ ->\ b)\ ->\ (R\ a\ ->\ R\ b)}\\ \mbox{\tt lift1\ f\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ {\char'134}ra1\ ->\ do\ a1\ <-\ ra1}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ step\ (f\ a1)} \eprog This takes a function of a single argument, \mbox{\tt f}, and creates a function in \mbox{\tt R} that executes the lifted function in a single step. Using \mbox{\tt lift1}, \mbox{\tt inc} becomes \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ R\ Integer\ ->\ R\ Integer}\\ \mbox{\tt inc\ i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift1\ (i+1)} \eprog This is better but still not ideal. First, we add \mbox{\tt lift2}: \bprog \mbox{\tt lift2\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (a\ ->\ b\ ->\ c)\ ->\ (R\ a\ ->\ R\ b\ ->\ R\ c)}\\ \mbox{\tt lift2\ f\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ {\char'134}ra1\ ra2\ ->\ do\ a1\ <-\ ra1}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ a2\ <-\ ra2}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ step\ (f\ a1\ a2)} \eprog Notice that this function explicitly sets the order of evaluation in the lifted function: the computation yielding \mbox{\tt a1} occurs before the computation for \mbox{\tt a2}. Using \mbox{\tt lift2}, we can create a new version of \mbox{\tt ==} in the \mbox{\tt R} monad: \bprog \mbox{\tt (==*)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Ord\ a\ =>\ R\ a\ ->\ R\ a\ ->\ R\ Bool}\\ \mbox{\tt (==*)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift2\ (==)} \eprog We had to use a slightly different name for this new function since \mbox{\tt ==} is already taken but in some cases we can use the same name for the lifted and unlifted function. This instance declaration allows all of the operators in \mbox{\tt Num} to be used in \mbox{\tt R}: \bprog \mbox{\tt instance\ Num\ a\ =>\ Num\ (R\ a)\ where}\\ \mbox{\tt \ \ (+)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift2\ (+)}\\ \mbox{\tt \ \ (-)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift2\ (-)}\\ \mbox{\tt \ \ negate\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift1\ negate}\\ \mbox{\tt \ \ (*)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift2\ (*)}\\ \mbox{\tt \ \ abs\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ lift1\ abs}\\ \mbox{\tt \ \ fromInteger\ \ \ \ \ \ \ \ \ \ \ =\ \ return\ .\ fromInteger} \eprog The \mbox{\tt fromInteger} function is applied implicitly to all integer constants in a Haskell program (see Section \ref{tut-num-constants}); this definition allows integer constants to have the type \mbox{\tt R\ Integer}. We can now, finally, write increment in a completely natural style: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ R\ Integer\ ->\ R\ Integer}\\ \mbox{\tt inc\ x\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ +\ 1} \eprog Note that we cannot lift the \mbox{\tt Eq} class in the same manner as the \mbox{\tt Num} class: the signature of \mbox{\tt ==*} is not compatible with allowable overloadings of \mbox{\tt ==} since the result of \mbox{\tt ==*} is \mbox{\tt R\ Bool} instead of \mbox{\tt Bool}. To express interesting computations in \mbox{\tt R} we will need a conditional. Since we can't use \mbox{\tt if} (it requires that the test be of type \mbox{\tt Bool} instead of \mbox{\tt R\ Bool}), we name the function \mbox{\tt ifR}: \bprog \mbox{\tt ifR\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ R\ Bool\ ->\ R\ a\ ->\ R\ a\ ->\ R\ a}\\ \mbox{\tt ifR\ tst\ thn\ els\ \ \ \ \ \ \ \ \ =\ \ do\ t\ <-\ tst}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ t\ then\ thn\ else\ els} \eprog Now we're ready for a larger program in the \mbox{\tt R} monad: \bprog \mbox{\tt fact\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ R\ Integer\ ->\ R\ Integer}\\ \mbox{\tt fact\ x\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ ifR\ (x\ ==*\ 0)\ 1\ (x\ *\ fact\ (x-1))} \eprog Now this isn't quite the same as an ordinary factorial function but still quite readable. The idea of providing new definitions for existing operations like \mbox{\tt +} or \mbox{\tt if} is an essential part of creating an embedded language in Haskell. Monads are particularly useful for encapsulating the semantics of these embedded languages in a clean and modular way. We're now ready to actually run some programs. This function runs a program in \mbox{\tt M} given a maximum number of computation steps: \bprog \mbox{\tt run\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Resource\ ->\ R\ a\ ->\ Maybe\ a}\\ \mbox{\tt run\ s\ (R\ p)\ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ case\ (p\ s)\ of\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ({\char'137},\ Left\ v)\ ->\ Just\ v}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\char'137}\ \ \ \ \ \ \ \ \ \ \ ->\ Nothing} \eprog We use the \mbox{\tt Maybe} type to deal with the possibility of the computation not finishing in the allotted number of steps. We can now compute \[\ba{lcl} \mbox{\tt run\ 10\ (fact\ 2)} \ \ \ &\red&\ \ \ \mbox{\tt Just\ 2}\\ \mbox{\tt run\ 10\ (fact\ 20)} \ \ \ &\red&\ \ \ \mbox{\tt Nothing}\\ \ea\] Finally, we can add some more interesting functionality to this monad. Consider the following function: \bprog \mbox{\tt (|||)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ R\ a\ ->\ R\ a\ ->\ R\ a} \eprog This runs two computations in parallel, returning the value of the first one to complete. One possible definition of this function is: \bprog \mbox{\tt c1\ |||\ c2\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ oneStep\ c1\ ({\char'134}c1'\ ->\ c2\ |||\ c1')}\\ \mbox{\tt \ \ \ where}\\ \mbox{\tt \ \ \ \ \ \ \ \ oneStep\ \ \ \ \ \ \ \ \ \ ::\ R\ a\ ->\ (R\ a\ ->\ R\ a)\ ->\ R\ a}\\ \mbox{\tt \ \ \ \ \ \ \ \ oneStep\ (R\ c1)\ f\ =}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ R\ ({\char'134}r\ ->\ case\ c1\ 1\ of}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (r',\ Left\ v)\ ->\ (r+r'-1,\ Left\ v)}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (r',\ Right\ c1')\ ->\ \ --\ r'\ must\ be\ 0}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ let\ R\ next\ =\ f\ c1'\ in}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ next\ (r+r'-1))} \eprog This takes a step in \mbox{\tt c1}, returning its value of \mbox{\tt c1} complete or, if \mbox{\tt c1} returns a suspended computation (\mbox{\tt c1'}), it evaluates \mbox{\tt c2\ |||\ c1'}. The \mbox{\tt oneStep} function takes a single step in its argument, either returning an evaluated value or passing the remainder of the computation into \mbox{\tt f}. The definition of \mbox{\tt oneStep} is simple: it gives \mbox{\tt c1} a 1 as its resource argument. If a final value is reached, this is returned, adjusting the returned step count (it is possible that a computation might return after taking no steps so the returned resource count isn't necessarily 0). If the computation suspends, a patched up resource count is passed to the final continuation. We can now evaluate expressions like \mbox{\tt run\ 100\ (fact\ (-1)\ |||\ (fact\ 3))} without looping since the two calculations are interleaved. (Our definition of \mbox{\tt fact} loops for \mbox{\tt -1}). Many variations are possible on this basic structure. For example, we could extend the state to include a trace of the computation steps. We could also embed this monad inside the standard \mbox{\tt IO} monad, allowing computations in \mbox{\tt M} to interact with the outside world. While this example is perhaps more advanced than others in this tutorial, it serves to illustrate the power of monads as a tool for defining the basic semantics of a system. We also present this example as a model of a small {\em Domain Specific Language}, something Haskell is particularly good at defining. Many other DSLs have been developed in Haskell; see {\tt haskell.org} for many more examples. Of particular interest are Fran, a language of reactive animations, and Haskore, a language of computer music. %**~footer haskell-98-tutorial-sources/numbers.tex0100644000106400000620000002744307116002315016604 0ustar jcpftp%**A Gentle Introduction to Haskell: Numbers %**~header \section{Numbers} Haskell provides a rich collection of numeric types, based on those of Scheme~\cite{RRRRS}, which in turn are based on Common Lisp~\cite{steele:common-lisp}. (Those languages, however, are dynamically typed.) The standard types include fixed- and arbitrary-precision integers, ratios (rational numbers) formed from each integer type, and single- and double-precision real and complex floating-point. We outline here the basic characteristics of the numeric type class structure and refer the reader to \see{numbers} for details. \subsection{Numeric Class Structure} The numeric type classes (class \mbox{\tt Num} and those that lie below it) account for many of the standard Haskell classes. We also note that \mbox{\tt Num} is a subclass of \mbox{\tt Eq}, but not of \mbox{\tt Ord}; this is because the order predicates do not apply to complex numbers. The subclass \mbox{\tt Real} of \mbox{\tt Num}, however, is a subclass of \mbox{\tt Ord} as well. The \mbox{\tt Num} class provides several basic operations common to all numeric types; these include, among others, addition, subtraction, negation, multiplication, and absolute value: \bprog \mbox{\tt (+),\ (-),\ (*)\ \ \ \ \ \ \ \ \ \ \ ::\ (Num\ a)\ =>\ a\ ->\ a\ ->\ a}\\ \mbox{\tt negate,\ abs\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Num\ a)\ =>\ a\ ->\ a} \eprog \syn{\mbox{\tt negate} is the function applied by Haskell's only prefix operator, minus; we can't call it \mbox{\tt (-)}, because that is the subtraction function, so this name is provided instead. For example, \mbox{\tt -x*y} is equivalent to \mbox{\tt negate\ (x*y)}. (Prefix minus has the same syntactic precedence as infix minus, which, of course, is lower than that of multiplication.)} Note that \mbox{\tt Num} does {\em not} provide a division operator; two different kinds of division operators are provided in two non-overlapping subclasses of \mbox{\tt Num}: The class \mbox{\tt Integral} provides whole-number division and remainder operations. The standard instances of \mbox{\tt Integral} are \mbox{\tt Integer} (unbounded or mathematical integers, also known as ``bignums'') and \mbox{\tt Int} (bounded, machine integers, with a range equivalent to at least 29-bit signed binary). A particular Haskell implementation might provide other integral types in addition to these. Note that \mbox{\tt Integral} is a subclass of \mbox{\tt Real}, rather than of \mbox{\tt Num} directly; this means that there is no attempt to provide Gaussian integers. All other numeric types fall in the class \mbox{\tt Fractional}, which provides the ordinary division operator \mbox{\tt (/)}. The further subclass \mbox{\tt Floating} contains trigonometric, logarithmic, and exponential functions. The \mbox{\tt RealFrac} subclass of \mbox{\tt Fractional} and \mbox{\tt Real} provides a function \mbox{\tt properFraction}, which decomposes a number into its whole and fractional parts, and a collection of functions that round to integral values by differing rules: \bprog \mbox{\tt properFraction\ \ \ \ \ \ \ \ \ \ ::\ (Fractional\ a,\ Integral\ b)\ =>\ a\ ->\ (b,a)}\\ \mbox{\tt truncate,\ round,}\\ \mbox{\tt floor,\ ceiling:\ \ \ \ \ \ \ \ \ ::\ (Fractional\ a,\ Integral\ b)\ =>\ a\ ->\ b} \eprog The \mbox{\tt RealFloat} subclass of \mbox{\tt Floating} and \mbox{\tt RealFrac} provides some specialized functions for efficient access to the components of a floating-point number, the {\em exponent} and {\em significand}. The standard types \mbox{\tt Float} and \mbox{\tt Double} fall in class \mbox{\tt RealFloat}. \subsection{Constructed Numbers} Of the standard numeric types, \mbox{\tt Int}, \mbox{\tt Integer}, \mbox{\tt Float}, and \mbox{\tt Double} are primitive. The others are made from these by type constructors. \mbox{\tt Complex} (found in the library \mbox{\tt Complex}) is a type constructor that makes a complex type in class \mbox{\tt Floating} from a \mbox{\tt RealFloat} type: \bprog \mbox{\tt data\ (RealFloat\ a)\ =>\ Complex\ a\ =\ !a\ :+\ !a\ \ deriving\ (Eq,\ Text)} \eprog The \mbox{\tt !} symbols are strictness flags; these were discussed in Section~ \ref{tut-strict-flag}. Notice the context \mbox{\tt RealFloat\ a}, which restricts the argument type; thus, the standard complex types are \mbox{\tt Complex\ Float} and \mbox{\tt Complex\ Double}. We can also see from the \mbox{\tt data} declaration that a complex number is written \mbox{$\it x$} \mbox{\tt :+} \mbox{$\it y$}; the arguments are the cartesian real and imaginary parts, respectively. Since \mbox{\tt :+} is a data constructor, we can use it in pattern matching: \bprog \mbox{\tt conjugate\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (RealFloat\ a)\ =>\ Complex\ a\ ->\ Complex\ a}\\ \mbox{\tt conjugate\ (x:+y)\ \ \ \ \ \ \ \ =\ \ x\ :+\ (-y)} \eprog Similarly, the type constructor \mbox{\tt Ratio} (found in the \mbox{\tt Rational} library) makes a rational type in class \mbox{\tt RealFrac} from an instance of \mbox{\tt Integral}. (\mbox{\tt Rational} is a type synonym for \mbox{\tt Ratio\ Integer}.) \mbox{\tt Ratio}, however, is an abstract type constructor. Instead of a data constructor like \mbox{\tt :+}, rationals use the `\mbox{\tt {\char'45}}' function to form a ratio from two integers. Instead of pattern matching, component extraction functions are provided: \bprog \mbox{\tt ({\char'45})\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Integral\ a)\ =>\ a\ ->\ a\ ->\ Ratio\ a}\\ \mbox{\tt numerator,\ denominator\ \ ::\ (Integral\ a)\ =>\ Ratio\ a\ ->\ a} \eprog Why the difference? Complex numbers in cartesian form are unique---there are no nontrivial identities involving \mbox{\tt :+}. On the other hand, ratios are not unique, but have a canonical (reduced) form that the implementation of the abstract data type must maintain; it is not necessarily the case, for instance, that \mbox{\tt numerator\ (x{\char'45}y)} is equal to \mbox{\tt x}, although the real part of \mbox{\tt x:+y} is always \mbox{\tt x}. \subsection{Numeric Coercions and Overloaded Literals} \label{tut-num-constants} The Standard Prelude and libraries provide several overloaded functions that serve as explicit coercions: \bprog \mbox{\tt fromInteger\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Num\ a)\ =>\ Integer\ ->\ a}\\ \mbox{\tt fromRational\ \ \ \ \ \ \ \ \ \ \ \ ::\ (Fractional\ a)\ =>\ Rational\ ->\ a}\\ \mbox{\tt toInteger\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Integral\ a)\ =>\ a\ ->\ Integer}\\ \mbox{\tt toRational\ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (RealFrac\ a)\ =>\ a\ ->\ Rational}\\ \mbox{\tt fromIntegral\ \ \ \ \ \ \ \ \ \ \ \ ::\ (Integral\ a,\ Num\ b)\ =>\ a\ ->\ b}\\ \mbox{\tt fromRealFrac\ \ \ \ \ \ \ \ \ \ \ \ ::\ (RealFrac\ a,\ Fractional\ b)\ =>\ a\ ->\ b}\\ \mbox{\tt }\\[-8pt] \mbox{\tt fromIntegral\ \ \ \ \ \ \ \ \ \ \ \ =\ \ fromInteger\ .\ toInteger}\\ \mbox{\tt fromRealFrac\ \ \ \ \ \ \ \ \ \ \ \ =\ \ fromRational\ .\ toRational} \eprog Two of these are implicitly used to provide overloaded numeric literals: An integer numeral (without a decimal point) is actually equivalent to an application of \mbox{\tt fromInteger} to the value of the numeral as an \mbox{\tt Integer}. Similarly, a floating numeral (with a decimal point) is regarded as an application of \mbox{\tt fromRational} to the value of the numeral as a \mbox{\tt Rational}. Thus, \mbox{\tt 7} has the type \mbox{\tt (Num\ a)\ =>\ a}, and \mbox{\tt 7.3} has the type \mbox{\tt (Fractional\ a)\ =>\ a}. This means that we can use numeric literals in generic numeric functions, for example: \bprog \mbox{\tt halve\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Fractional\ a)\ =>\ a\ ->\ a}\\ \mbox{\tt halve\ x\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ x\ *\ 0.5} \eprog This rather indirect way of overloading numerals has the additional advantage that the method of interpreting a numeral as a number of a given type can be specified in an \mbox{\tt Integral} or \mbox{\tt Fractional} instance declaration (since \mbox{\tt fromInteger} and \mbox{\tt fromRational} are operators of those classes, respectively). For example, the \mbox{\tt Num} instance of \mbox{\tt (RealFloat\ a)\ =>\ Complex\ a} contains this method: \bprog \mbox{\tt fromInteger\ x\ \ \ \ \ \ \ \ \ \ \ =\ \ fromInteger\ x\ :+\ 0} \eprog This says that a \mbox{\tt Complex} instance of \mbox{\tt fromInteger} is defined to produce a complex number whose real part is supplied by an appropriate \mbox{\tt RealFloat} instance of \mbox{\tt fromInteger}. In this manner, even user-defined numeric types (say, quaternions) can make use of overloaded numerals. As another example, recall our first definition of \mbox{\tt inc} from Section \ref{tut-values-etc}: \bprog \mbox{\tt inc\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Integer\ ->\ Integer}\\ \mbox{\tt inc\ n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ n+1} \eprog Ignoring the type signature, the most general type of \mbox{\tt inc} is \mbox{\tt (Num\ a)\ =>\ a->a}. The explicit type signature is legal, however, since it is {\em more specific} than the principal type (a more general type signature would cause a static error). The type signature has the effect of restricting \mbox{\tt inc}'s type, and in this case would cause something like \mbox{\tt inc\ (1::Float)} to be ill-typed. \subsection{Default Numeric Types} Consider the following function definition: \bprog \mbox{\tt rms\ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Floating\ a)\ =>\ a\ ->\ a\ ->\ a}\\ \mbox{\tt rms\ x\ y\ \ \ \ \ \ \ \ \ \ =\ \ sqrt\ ((x{\char'136}2\ +\ y{\char'136}2)\ *\ 0.5)} \eprog The exponentiation function \mbox{\tt ({\char'136})} (one of three different standard exponentiation operators with different typings, see \S{6.8.5}) has the type \mbox{\tt (Num\ a,\ Integral\ b)\ =>\ a\ ->\ b\ ->\ a}, and since \mbox{\tt 2} has the type \mbox{\tt (Num\ a)\ =>\ a}, the type of \mbox{\tt x{\char'136}2} is \mbox{\tt (Num\ a,\ Integral\ b)\ =>\ a}. This is a problem; there is no way to resolve the overloading associated with the type variable \mbox{\tt b}, since it is in the context, but has otherwise vanished from the type expression. Essentially, the programmer has specified that \mbox{\tt x} should be squared, but has not specified whether it should be squared with an \mbox{\tt Int} or an \mbox{\tt Integer} value of two. Of course, we can fix this: \bprog \mbox{\tt rms\ x\ y\ \ \ \ \ \ \ \ \ \ =\ \ sqrt\ ((x\ {\char'136}\ (2::Integer)\ +\ y\ {\char'136}\ (2::Integer))\ *\ 0.5)} \eprog It's obvious that this sort of thing will soon grow tiresome, however. In fact, this kind of overloading ambiguity is not restricted to numbers: \bprog \mbox{\tt show\ (read\ "xyz")} \eprog As what type is the string supposed to be read? This is more serious than the exponentiation ambiguity, because there, any \mbox{\tt Integral} instance will do, whereas here, very different behavior can be expected depending on what instance of \mbox{\tt Text} is used to resolve the ambiguity. Because of the difference between the numeric and general cases of the overloading ambiguity problem, Haskell provides a solution that is restricted to numbers: Each module may contain a {\em default declaration,} consisting of the keyword \mbox{\tt default} followed by a parenthesized, comma-separated list of numeric monotypes (types with no variables). When an ambiguous type variable is discovered (such as \mbox{\tt b}, above), if at least one of its classes is numeric and all of its classes are standard, the default list is consulted, and the first type from the list that will satisfy the context of the type variable is used. For example, if the default declaration \mbox{\tt default\ (Int,\ Float)} is in effect, the ambiguous exponent above will be resolved as type \mbox{\tt Int}. (See \see{default-decls} for more details.) The ``default default'' is \mbox{\tt (Integer,\ Double)}, but \mbox{\tt (Integer,\ Rational,\ Double)} may also be appropriate. Very cautious programmers may prefer \mbox{\tt default\ ()}, which provides no defaults. %**~footer haskell-98-tutorial-sources/modules.tex0100644000106400000620000002275307116002315016600 0ustar jcpftp%**A Gentle Introduction to Haskell: Modules %**~header \section{Modules} \label{tut-modules} A Haskell program consists of a collection of {\em modules}. A module in Haskell serves the dual purpose of controlling name-spaces and creating abstract data types. The top level of a module contains any of the various declarations we have discussed: fixity declarations, data and type declarations, class and instance declarations, type signatures, function definitions, and pattern bindings. Except for the fact that import declarations (to be described shortly) must appear first, the declarations may appear in any order (the top-level scope is mutually recursive). Haskell's module design is relatively conservative: the name-space of modules is completely flat, and modules are in no way ``first-class.'' Module names are alphanumeric and must begin with an uppercase letter. There is no formal connection between a Haskell module and the file system that would (typically) support it. In particular, there is no connection between module names and file names, and more than one module could conceivably reside in a single file (one module may even span several files). Of course, a particular implementation will most likely adopt conventions that make the connection between modules and files more stringent. Technically speaking, a module is really just one big declaration which begins with the keyword \mbox{\tt module}; here's an example for a module whose name is \mbox{\tt Tree}: \bprog \mbox{\tt module\ Tree\ (\ Tree(Leaf,Branch),\ fringe\ )\ where}\\ \mbox{\tt }\\[-8pt] \mbox{\tt data\ Tree\ a\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ Leaf\ a\ |\ Branch\ (Tree\ a)\ (Tree\ a)\ }\\ \mbox{\tt }\\[-8pt] \mbox{\tt fringe\ ::\ Tree\ a\ ->\ [a]}\\ \mbox{\tt fringe\ (Leaf\ x)\ \ \ \ \ \ \ \ \ \ \ \ =\ [x]}\\ \mbox{\tt fringe\ (Branch\ left\ right)\ =\ fringe\ left\ ++\ fringe\ right} \eprog The type \mbox{\tt Tree} and the function \mbox{\tt fringe} should be familiar; they were given as examples in Section \ref{tut-recursive-types}. \syn{Because of the \mbox{\tt where} keyword, layout is active at the top level of a module, and thus the declarations must all line up in the same column (typically the first). Also note that the module name is the same as that of the type; this is allowed.} This module explicitly {\em exports} \mbox{\tt Tree}, \mbox{\tt Leaf}, \mbox{\tt Branch}, and \mbox{\tt fringe}. If the export list following the \mbox{\tt module} keyword is omitted, {\em all} of the names bound at the top level of the module would be exported. (In the above example everything is explicitly exported, so the effect would be the same.) Note that the name of a type and its constructors have be grouped together, as in \mbox{\tt Tree(Leaf,Branch)}. As short-hand, we could also write \mbox{\tt Tree(..)}. Exporting a subset of the constructors is also possible. The names in an export list need not be local to the exporting module; any name in scope may be listed in an export list. The \mbox{\tt Tree} module may now be {\em imported} into some other module: \bprog \mbox{\tt module\ Main\ (main)\ where}\\ \mbox{\tt import\ Tree\ (\ Tree(Leaf,Branch),\ fringe\ )}\\ \mbox{\tt }\\[-8pt] \mbox{\tt main\ =\ print\ (fringe\ (Branch\ (Leaf\ 1)\ (Leaf\ 2)))} \eprog The various items being imported into and exported out of a module are called {\em entities}. Note the explicit import list in the import declaration; omitting it would cause all entities exported from \mbox{\tt Tree} to be imported. \subsection{Qualified Names} There is an obvious problem with importing names directly into the namespace of module. What if two imported modules contain different entities with the same name? Haskell solves this problem using \mbox{$\it qualified\ names$}. An import declaration may use the \mbox{\tt qualified} keyword to cause the imported names to be prefixed by the name of the module imported. These prefixes are followed by the `\mbox{\tt .}' character without intervening whitespace. \syn{Qualifiers are part of the lexical syntax. Thus, \mbox{\tt A.x} and \mbox{\tt A\ .\ x} are quite different: the first is a qualified name and the second a use of the infix `\mbox{\tt .}' function.} For example, using the \mbox{\tt Tree} module introduced above: \bprog \mbox{\tt module\ Fringe(fringe)\ where}\\ \mbox{\tt import\ Tree(Tree(..))}\\ \mbox{\tt }\\[-8pt] \mbox{\tt fringe\ ::\ Tree\ a\ ->\ [a]\ \ \ --\ A\ different\ definition\ of\ fringe}\\ \mbox{\tt fringe\ (Leaf\ x)\ =\ [x]}\\ \mbox{\tt fringe\ (Branch\ x\ y)\ =\ fringe\ x}\\ \mbox{\tt }\\[-8pt] \mbox{\tt module\ Main\ where}\\ \mbox{\tt import\ Tree\ (\ Tree(Leaf,Branch),\ fringe\ )}\\ \mbox{\tt import\ qualified\ Fringe\ (\ fringe\ )\ \ }\\ \mbox{\tt }\\[-8pt] \mbox{\tt main\ =\ do\ print\ (fringe\ (Branch\ (Leaf\ 1)\ (Leaf\ 2)))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ print\ (Fringe.fringe\ (Branch\ (Leaf\ 1)\ (Leaf\ 2)))} \eprog Some Haskell programmers prefer to use qualifiers for all imported entities, making the source of each name explicit with every use. Others prefer short names and only use qualifiers when absolutely necessary. Qualifiers are used to resolve conflicts between different entities which have the same name. But what if the same entity is imported from more than one module? Fortunately, such name clashes are allowed: an entity can be imported by various routes without conflict. The compiler knows whether entities from different modules are actually the same. \subsection{Abstract Data Types} \label{tut-ADTs} Aside from controlling namespaces, modules provide the only way to build abstract data types (ADTs) in Haskell. For example, the characteristic feature of an ADT is that the {\em representation type} is {\em hidden}; all operations on the ADT are done at an abstract level which does not depend on the representation. For example, although the \mbox{\tt Tree} type is simple enough that we might not normally make it abstract, a suitable ADT for it might include the following operations: \bprog \mbox{\tt data\ Tree\ a\ \ \ \ \ \ \ \ \ \ \ \ \ --\ just\ the\ type\ name\ }\\ \mbox{\tt leaf\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ a\ ->\ Tree\ a}\\ \mbox{\tt branch\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Tree\ a\ ->\ Tree\ a\ ->\ Tree\ a}\\ \mbox{\tt cell\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Tree\ a\ ->\ a}\\ \mbox{\tt left,\ right\ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Tree\ a\ ->\ Tree\ a}\\ \mbox{\tt isLeaf\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ Tree\ a\ ->\ Bool} \eprog A module supporting this is: \bprog \mbox{\tt module\ TreeADT\ (Tree,\ leaf,\ branch,\ cell,\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ left,\ right,\ isLeaf)\ where}\\ \mbox{\tt }\\[-8pt] \mbox{\tt data\ Tree\ a\ \ \ \ \ \ \ \ \ \ \ \ \ =\ Leaf\ a\ |\ Branch\ (Tree\ a)\ (Tree\ a)\ }\\ \mbox{\tt }\\[-8pt] \mbox{\tt leaf\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ Leaf}\\ \mbox{\tt branch\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ Branch}\\ \mbox{\tt cell\ \ (Leaf\ a)\ \ \ \ \ \ \ \ \ \ =\ a}\\ \mbox{\tt left\ \ (Branch\ l\ r)\ \ \ \ \ \ =\ l}\\ \mbox{\tt right\ (Branch\ l\ r)\ \ \ \ \ \ =\ r}\\ \mbox{\tt isLeaf\ \ \ (Leaf\ {\char'137})\ \ \ \ \ \ \ =\ True}\\ \mbox{\tt isLeaf\ \ \ {\char'137}\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ False} \eprog Note in the export list that the type name \mbox{\tt Tree} appears alone (i.e.~without its constructors). Thus \mbox{\tt Leaf} and \mbox{\tt Branch} are not exported, and the only way to build or take apart trees outside of the module is by using the various (abstract) operations. Of course, the advantage of this information hiding is that at a later time we could {\em change} the representation type without affecting users of the type. \subsection{More Features} \label{tut-rules} Here is a brief overview of some other aspects of the module system. See the report for more details. \begin{itemize} \item An \mbox{\tt import} declaration may selectively hide entities using a \mbox{\tt hiding} clause in the import declaration. This is useful for explicitly excluding names that are used for other purposes without having to use qualifiers for other imported names from the module. \item An \mbox{\tt import} may contain an \mbox{\tt as} clause to specify a different qualifier than the name of the importing module. This can be used to shorten qualifiers from modules with long names or to easily adapt to a change in module name without changing all qualifiers. \item Programs implicitly import the \mbox{\tt Prelude} module. An explicit import of the Prelude overrides the implicit import of all Prelude names. Thus, \bprog \mbox{\tt import\ Prelude\ hiding\ length} \eprog will not import \mbox{\tt length} from the Standard Prelude, allowing the name \mbox{\tt length} to be defined differently. \item Instance declarations are not explicitly named in import or export lists. Every module exports all of its instance declarations and every import brings all instance declarations into scope. \item Class methods may be named either in the manner of data constructors, in parentheses following the class name, or as ordinary variables. \end{itemize} Although Haskell's module system is relatively conservative, there are many rules concerning the import and export of values. Most of these are obvious---for instance, it is illegal to import two different entities having the same name into the same scope. Other rules are not so obvious---for example, for a given type and class, there cannot be more than one \mbox{\tt instance} declaration for that combination of type and class anywhere in the program. The reader should read the Report for details (\see{modules}). %**~footer haskell-98-tutorial-sources/pitfalls.tex0100644000106400000620000000675207116002315016747 0ustar jcpftp%**A Gentle Introduction to Haskell: Typing Pitfalls %**~header \section{Typing Pitfalls} This short section give an intuitive description of a few common problems that novices run into using Haskell's type system. \subsection{Let-Bound Polymorphism} Any language using the Hindley-Milner type system has what is called {\em let-bound polymorphism}, because identifiers not bound using a \mbox{\tt let} or \mbox{\tt where} clause (or at the top level of a module) are limited with respect to their polymorphism. In particular, a {\em lambda-bound} function (i.e., one passed as argument to another function) cannot be instantiated in two different ways. For example, this program is illegal: \bprog \mbox{\tt let\ f\ g\ \ =\ \ (g\ [],\ g\ 'a')\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ --\ ill-typed\ expression}\\ \mbox{\tt in\ f\ ({\char'134}x->x)} \eprog because \mbox{\tt g}, bound to a lambda abstraction whose principal type is \mbox{\tt a->a}, is used within \mbox{\tt f} in two different ways: once with type \mbox{\tt [a]->[a]}, and once with type \mbox{\tt Char->Char}. \subsection{Numeric Overloading} It is easy to forget at times that numerals are {\em overloaded,} and {\em not implicitly coerced} to the various numeric types, as in many other languages. More general numeric expressions sometimes cannot be quite so generic. A common numeric typing error is something like the following: \bprog \mbox{\tt average\ xs\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ sum\ xs\ /\ length\ xs\ \ \ \ \ \ \ \ \ \ \ --\ Wrong!} \eprog \mbox{\tt (/)} requires fractional arguments, but \mbox{\tt length}'s result is an \mbox{\tt Int}. The type mismatch must be corrected with an explicit coercion: \bprog \mbox{\tt average\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Fractional\ a)\ =>\ [a]\ ->\ a}\\ \mbox{\tt average\ xs\ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ sum\ xs\ /\ fromIntegral\ (length\ xs)} \eprog \subsection{The Monomorphism Restriction} The Haskell type system contains a restriction related to type classes that is not found in ordinary Hindley-Milner type systems: the {\em monomorphism restriction}. The reason for this restriction is related to a subtle type ambiguity and is explained in full detail in the Report (\see{sect:monomorphism-restriction}). A simpler explanation follows: The monomorphism restriction says that any identifier bound by a pattern binding (which includes bindings to a single identifier), and having no explicit type signature, must be {\em monomorphic}. An identifier is monomorphic if is either not overloaded, or is overloaded but is used in at most one specific overloading and is not exported. Violations of this restriction result in a static type error. The simplest way to avoid the problem is to provide an explicit type signature. Note that {\em any} type signature will do (as long it is type correct). A common violation of the restriction happens with functions defined in a higher-order manner, as in this definition of \mbox{\tt sum} from the Standard Prelude: \bprog \mbox{\tt sum\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ foldl\ (+)\ 0} \eprog As is, this would cause a static type error. We can fix the problem by adding the type signature: \bprog \mbox{\tt sum\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Num\ a)\ =>\ [a]\ ->\ a} \eprog Also note that this problem would not have arisen if we had written: \bprog \mbox{\tt sum\ xs\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ foldl\ (+)\ 0\ xs} \eprog because the restriction only applies to pattern bindings. %**~footer haskell-98-tutorial-sources/arrays.tex0100644000106400000620000004044007116002315016422 0ustar jcpftp%**A Gentle Introduction to Haskell: Arrays %**~header \section{Arrays} Ideally, arrays in a functional language would be regarded simply as functions from indices to values, but pragmatically, in order to assure efficient access to array elements, we need to be sure we can take advantage of the special properties of the domains of these functions, which are isomorphic to finite contiguous subsets of the integers. Haskell, therefore, does not treat arrays as general functions with an application operation, but as abstract data types with a subscript operation. Two main approaches to functional arrays may be discerned: {\em incremental} and {\em monolithic} definition. In the incremental case, we have a function that produces an empty array of a given size and another that takes an array, an index, and a value, producing a new array that differs from the old one only at the given index. Obviously, a naive implementation of such an array semantics would be intolerably inefficient, either requiring a new copy of an array for each incremental redefinition, or taking linear time for array lookup; thus, serious attempts at using this approach employ sophisticated static analysis and clever run-time devices to avoid excessive copying. The monolithic approach, on the other hand, constructs an array all at once, without reference to intermediate array values. Although Haskell has an incremental array update operator, the main thrust of the array facility is monolithic. Arrays are not part of the Standard Prelude---the standard library contains the array operators. Any module using arrays must import the \mbox{\tt Array} module. \subsection{Index types} The \mbox{\tt Ix} library defines a type class of array indices: \bprog \mbox{\tt class\ \ (Ord\ a)\ =>\ Ix\ a\ \ where}\\ \mbox{\tt \ \ \ \ range\ \ \ \ \ \ \ ::\ (a,a)\ ->\ [a]}\\ \mbox{\tt \ \ \ \ index\ \ \ \ \ \ \ ::\ (a,a)\ a\ ->\ Int}\\ \mbox{\tt \ \ \ \ inRange\ \ \ \ \ ::\ (a,a)\ ->\ a\ ->\ Bool} \eprog Instance declarations are provided for \mbox{\tt Int}, \mbox{\tt Integer}, \mbox{\tt Char}, \mbox{\tt Bool}, and tuples of \mbox{\tt Ix} types up to length 5; in addition, instances may be automatically derived for enumerated and tuple types. We regard the primitive types as vector indices, and tuples as indices of multidimensional rectangular arrays. Note that the first argument of each of the operations of class \mbox{\tt Ix} is a pair of indices; these are typically the {\em bounds} (first and last indices) of an array. For example, the bounds of a 10-element, zero-origin vector with \mbox{\tt Int} indices would be \mbox{\tt (0,9)}, while a 100 by 100 1-origin matrix might have the bounds \mbox{\tt ((1,1),(100,100))}. (In many other languages, such bounds would be written in a form like \mbox{\tt 1:100,\ 1:100}, but the present form fits the type system better, since each bound is of the same type as a general index.) The \mbox{\tt range} operation takes a bounds pair and produces the list of indices lying between those bounds, in index order. For example, \[ \mbox{\tt range\ (0,4)}\ \ \ \ \red\ \ \ \ \mbox{\tt [0,1,2,3,4]} \] \[ \mbox{\tt range\ ((0,0),(1,2))}\ \ \ \ \red\ \ \ \ % \mbox{\tt [(0,0),\ (0,1),\ (0,2),\ (1,0),\ (1,1),\ (1,2)]} \] The \mbox{\tt inRange} predicate determines whether an index lies between a given pair of bounds. (For a tuple type, this test is performed component-wise.) Finally, the \mbox{\tt index} operation allows a particular element of an array to be addressed: given a bounds pair and an in-range index, the operation yields the zero-origin ordinal of the index within the range; for example: \[ \mbox{\tt index\ (1,9)\ 2}\ \ \ \ \red\ \ \ \ \mbox{\tt 1} \] \[ \mbox{\tt index\ ((0,0),(1,2))\ (1,1)}\ \ \ \ \red\ \ \ \ \mbox{\tt 4} \] \subsection{Array Creation} Haskell's monolithic array creation function forms an array from a pair of bounds and a list of index-value pairs (an {\em association list}): \bprog \mbox{\tt array\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Ix\ a)\ =>\ (a,a)\ ->\ [(a,b)]\ ->\ Array\ a\ b} \eprog Here, for example, is a definition of an array of the squares of numbers from 1 to 100: \bprog \mbox{\tt squares\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\ \ array\ (1,100)\ [(i,\ i*i)\ |\ i\ <-\ [1..100]]} \eprog This array expression is typical in using a list comprehension for the association list; in fact, this usage results in array expressions much like the {\em array comprehensions} of the language Id~\cite{id-manual}. Array subscripting is performed with the infix operator \mbox{\tt !}, and the bounds of an array can be extracted with the function \mbox{\tt bounds}: \[ \mbox{\tt squares!7}\ \ \ \ \red\ \ \ \ \mbox{\tt 49} \] \[ \mbox{\tt bounds\ squares}\ \ \ \ \red\ \ \ \ \mbox{\tt (1,100)} \] We might generalize this example by parameterizing the bounds and the function to be applied to each index: \bprog \mbox{\tt mkArray\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ::\ (Ix\ a)\ =>\ (a\ ->\ b)\ ->\ (a,a)\ ->\ Array\ a\ b}\\ \mbox{\tt mkArray\ f\ bnds\ \ \ \ \ \ \ \ \ \ =\ \ array\ bnds\ [(i,\ f\ i)\ |\ i\ <-\ range\ bnds]} \eprog Thus, we could define \mbox{\tt squares} as \mbox{\tt mkArray\ ({\char'134}i\ ->\ i\ *\ i)\ (1,100)}. Many arrays are defined recursively; that is, with the values of some elements depending on the values of others. Here, for example, we have a function returning an array of Fibonacci numbers: \bprog \mbox{\tt fibs\ \ \ \ ::\ Int\ ->\ Array\ Int\ Int}\\ \mbox{\tt fibs\ n\ \ =\ \ a\ \ where\ a\ =\ array\ (0,n)\ ([(0,\ 1),\ (1,\ 1)]\ ++\ }\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [(i,\ a!(i-2)\ +\ a!(i-1))\ |\ i\ <-\ [2..n]])} \eprog Another example of such a recurrence is the \mbox{$\it n$} by \mbox{$\it n$} {\em wavefront} matrix, in which elements of the first row and first column all have the value \mbox{$\it 1$} and other elements are sums of their neighbors to the west, northwest, and north: \bprog \mbox{\tt wavefront\ \ \ \ \ \ \ ::\ Int\ ->\ Array\ (Int,Int)\ Int}\\ \mbox{\tt wavefront\ n\ \ \ \ \ =\ \ a\ \ where}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ a\ =\ array\ ((1,1),(n,n))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ([((1,j),\ 1)\ |\ j\ <-\ [1..n]]\ ++}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [((i,1),\ 1)\ |\ i\ <-\ [2..n]]\ ++}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [((i,j),\ a!(i,j-1)\ +\ a!(i-1,j-1)\ +\ a!(i-1,j))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ i\ <-\ [2..n],\ j\ <-\ [2..n]])} \eprog The wavefront matrix is so called because in a parallel implementation, the recurrence dictates that the computation can begin with the first row and column in parallel and proceed as a wedge-shaped wave, traveling from northwest to southeast. It is important to note, however, that no order of computation is specified by the association list. In each of our examples so far, we have given a unique association for each index of the array and only for the indices within the bounds of the array, and indeed, we must do this in general for an array be fully defined. An association with an out-of-bounds index results in an error; if an index is missing or appears more than once, however, there is no immediate error, but the value of the array at that index is then undefined, so that subscripting the array with such an index yields an error. \subsection{Accumulation} We can relax the restriction that an index appear at most once in the association list by specifying how to combine multiple values associated with a single index; the result is called an {\em accumulated array}: \bprog \mbox{\tt accumArray\ ::\ (Ix\ a)\ ->\ (b\ ->\ c\ ->\ b)\ ->\ b\ ->\ (a,a)\ ->\ [Assoc\ a\ c]\ ->\ Array\ a\ b} \eprog The first argument of \mbox{\tt accumArray} is the {\em accumulating function}, the second is an initial value (the same for each element of the array), and the remaining arguments are bounds and an association list, as with the \mbox{\tt array} function. Typically, the accumulating function is \mbox{\tt (+)}, and the initial value, zero; for example, this function takes a pair of bounds and a list of values (of an index type) and yields a histogram; that is, a table of the number of occurrences of each value within the bounds: \bprog \mbox{\tt hist\ \ \ \ \ \ \ \ \ \ \ \ ::\ (Ix\ a,\ Integral\ b)\ =>\ (a,a)\ ->\ [a]\ ->\ Array\ a\ b}\\ \mbox{\tt hist\ bnds\ is\ \ \ \ =\ \ accumArray\ (+)\ 0\ bnds\ [(i,\ 1)\ |\ i\ <-\ is,\ inRange\ bnds\ i]} \eprog Suppose we have a collection of measurements on the interval \mbox{$\it [a,b)$}, and we want to divide the interval into decades and count the number of measurements within each: \bprog \mbox{\tt decades\ \ \ \ \ \ \ \ \ ::\ (RealFrac\ a)\ =>\ a\ ->\ a\ ->\ [a]\ ->\ Array\ Int\ Int}\\ \mbox{\tt decades\ a\ b\ \ \ \ \ =\ \ hist\ (0,9)\ .\ map\ decade}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ where\ decade\ x\ =\ floor\ ((x\ -\ a)\ *\ s)}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ s\ \ \ \ \ \ \ \ =\ 10\ /\ (b\ -\ a)} \eprog \subsection{Incremental updates} In addition to the monolithic array creation functions, Haskell also has an incremental array update function, written as the infix operator \mbox{\tt //}; the simplest case, an array \mbox{\tt a} with element \mbox{\tt i} updated to \mbox{\tt v}, is written \mbox{\tt a\ //\ [(i,\ v)]}. The reason for the square brackets is that the left argument of \mbox{\tt (//)} is an association list, usually containing a proper subset of the indices of the array: \bprog \mbox{\tt (//)\ \ \ \ \ \ \ \ \ \ \ \ ::\ (Ix\ a)\ =>\ Array\ a\ b\ ->\ [(a,b)]\ ->\ Array\ a\ b} \eprog As with the \mbox{\tt array} function, the indices in the association list must be unique for the values to be defined. For example, here is a function to interchange two rows of a matrix: \bprog \mbox{\tt swapRows\ ::\ (Ix\ a,\ Ix\ b,\ Enum\ b)\ =>\ a\ ->\ a\ ->\ Array\ (a,b)\ c\ ->\ Array\ (a,b)\ c}\\ \mbox{\tt swapRows\ i\ i'\ a\ =\ \ a\ //\ ([((i\ ,j),\ a!(i',j))\ |\ j\ <-\ [jLo..jHi]]\ ++}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [((i',j),\ a!(i\ ,j))\ |\ j\ <-\ [jLo..jHi]])}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ where\ ((iLo,jLo),(iHi,jHi))\ =\ bounds\ a} \eprog The concatenation here of two separate list comprehensions over the same list of \mbox{\tt j} indices is, however, a slight inefficiency; it's like writing two loops where one will do in an imperative language. Never fear, we can perform the equivalent of a loop fusion optimization in Haskell: \bprog \mbox{\tt swapRows\ i\ i'\ a\ =\ \ a\ //\ [assoc\ |\ j\ <-\ [jLo..jHi],}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ assoc\ <-\ [((i\ ,j),\ a!(i',j)),}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ((i',j),\ a!(i,\ j))]\ ]}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ where\ ((iLo,jLo),(iHi,jHi))\ =\ bounds\ a} \eprog \subsection{An example: Matrix Multiplication} We complete our introduction to Haskell arrays with the familiar example of matrix multiplication, taking advantage of overloading to define a fairly general function. Since only multiplication and addition on the element type of the matrices is involved, we get a function that multiplies matrices of any numeric type unless we try hard not to. Additionally, if we are careful to apply only \mbox{\tt (!)} and the operations of \mbox{\tt Ix} to indices, we get genericity over index types, and in fact, the four row and column index types need not all be the same. For simplicity, however, we require that the left column indices and right row indices be of the same type, and moreover, that the bounds be equal: \bprog \mbox{\tt matMult\ \ \ \ \ \ \ \ \ ::\ (Ix\ a,\ Ix\ b,\ Ix\ c,\ Num\ d)\ =>}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Array\ (a,b)\ d\ ->\ Array\ (b,c)\ d\ ->\ Array\ (a,c)\ d}\\ \mbox{\tt matMult\ x\ y\ \ \ \ \ =\ \ array\ resultBounds}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [((i,j),\ sum\ [x!(i,k)\ *\ y!(k,j)\ |\ k\ <-\ range\ (lj,uj)])}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ i\ <-\ range\ (li,ui),}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ j\ <-\ range\ (lj',uj')\ ]}\\ \mbox{\tt \ \ \ \ \ \ \ \ where\ ((li,lj),(ui,uj))\ \ \ \ \ \ \ \ \ =\ \ bounds\ x}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ ((li',lj'),(ui',uj'))\ \ \ \ \ =\ \ bounds\ y}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ resultBounds}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ (lj,uj)==(li',ui')\ \ \ \ =\ \ ((li,lj'),(ui,uj'))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ otherwise\ \ \ \ \ \ \ \ \ \ \ \ \ =\ error\ "matMult:\ incompatible\ bounds"} \eprog As an aside, we can also define \mbox{\tt matMult} using \mbox{\tt accumArray}, resulting in a presentation that more closely resembles the usual formulation in an imperative language: \bprog \mbox{\tt matMult\ x\ y\ \ \ \ \ =\ \ accumArray\ (+)\ 0\ resultBounds}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [((i,j),\ x!(i,k)\ *\ y!(k,j))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ i\ <-\ range\ (li,ui),}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ j\ <-\ range\ (lj',uj')}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ k\ <-\ range\ (lj,uj)\ \ ]}\\ \mbox{\tt \ \ \ \ \ \ \ \ where\ ((li,lj),(ui,uj))\ \ \ \ \ \ \ \ \ =\ \ bounds\ x}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ ((li',lj'),(ui',uj'))\ \ \ \ \ =\ \ bounds\ y}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ resultBounds}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ (lj,uj)==(li',ui')\ \ \ \ =\ \ ((li,lj'),(ui,uj'))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ otherwise\ \ \ \ \ \ \ \ \ \ \ \ \ =\ error\ "matMult:\ incompatible\ bounds"} \eprog We can generalize further by making the function higher-order, simply replacing \mbox{\tt sum} and \mbox{\tt (*)} by functional parameters: \bprog \mbox{\tt genMatMult\ \ \ \ \ \ ::\ (Ix\ a,\ Ix\ b,\ Ix\ c)\ =>}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ([f]\ ->\ g)\ ->\ (d\ ->\ e\ ->\ f)\ ->}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Array\ (a,b)\ d\ ->\ Array\ (b,c)\ e\ ->\ Array\ (a,c)\ g}\\ \mbox{\tt genMatMult\ sum'\ star\ x\ y\ \ =}\\ \mbox{\tt \ \ \ \ \ \ array\ resultBounds}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ [((i,j),\ sum'\ [x!(i,k)\ `star`\ y!(k,j)\ |\ k\ <-\ range\ (lj,uj)])}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ i\ <-\ range\ (li,ui),}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ j\ <-\ range\ (lj',uj')\ ]}\\ \mbox{\tt \ \ \ \ \ \ \ \ where\ ((li,lj),(ui,uj))\ \ \ \ \ \ \ \ \ =\ \ bounds\ x}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ ((li',lj'),(ui',uj'))\ \ \ \ \ =\ \ bounds\ y}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ resultBounds}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ (lj,uj)==(li',ui')\ \ \ \ =\ \ ((li,lj'),(ui,uj'))}\\ \mbox{\tt \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ otherwise\ \ \ \ \ \ \ \ \ \ \ \ \ =\ error\ "matMult:\ incompatible\ bounds"} \eprog APL fans will recognize the usefulness of functions like the following: \bprog \mbox{\tt genMatMult\ maximum\ (-)}\\ \mbox{\tt genMatMult\ and\ (==)} \eprog With the first of these, the arguments are numeric matrices, and the \mbox{$\it (i,j)$}-th element of the result is the maximum difference between corresponding elements of the \mbox{$\it i$}-th row and \mbox{$\it j$}-th column of the inputs. In the second case, the arguments are matrices of any equality type, and the result is a Boolean matrix in which element \mbox{$\it (i,j)$} is \mbox{\tt True} if and only if the \mbox{$\it i$}-th row of the first argument and \mbox{$\it j$}-th column of the second are equal as vectors. Notice that the element types of \mbox{\tt genMatMult} need not be the same, but merely appropriate for the function parameter \mbox{\tt star}. We could generalize still further by dropping the requirement that the first column index and second row index types be the same; clearly, two matrices could be considered conformable as long as the lengths of the columns of the first and the rows of the second are equal. The reader may wish to derive this still more general version. ({\bf Hint:} Use the \mbox{\tt index} operation to determine the lengths.) %**~footer haskell-98-tutorial-sources/end.tex0100644000106400000620000000157707116002315015677 0ustar jcpftp%**A Gentle Introduction to Haskell: The Next Stage %**~eheader \section{The Next Stage} A large collection of Haskell resources is available on the web at \mbox{\tt haskell.org}. Here you will find compilers, demos, papers, and much valuable information about Haskell and functional programming. Haskell compilers or interpreters run on almost all hardware and operating systems. The Hugs system is both small and portable -- it is an excellent vehicle for learning Haskell. \section{Acknowledgements} Thanks to Patricia Fasel and Mark Mundt at Los Alamos, and Nick Carriero, Charles Consel, Amir Kishon, Sandra Loosemore, Martin Odersky, and David Rochberg at Yale University for their quick readings of earlier drafts of this manuscript. Special thanks to Erik Meijer for his extensive comments on the new material added for version 1.4 of this tutorial. %**~efooter haskell-98-tutorial-sources/haskell-tutorial.log0100644000106400000620000001414107121452210020364 0ustar jcpftpThis is TeX, Version 3.14159 (Web2C 7.3.1) (format=latex 1999.9.25) 13 JUN 2000 10:34 **haskell-tutorial.tex (haskell-tutorial.tex LaTeX2e <1998/12/01> patch level 1 Babel and hyphenation patterns for american, french, german, ngerman, i talian, nohyphenation, loaded. (/usr/share/texmf/tex/latex/base/article.cls Document Class: article 1999/01/07 v1.4a Standard LaTeX document class (/usr/share/texmf/tex/latex/base/size11.clo File: size11.clo 1999/01/07 v1.4a Standard LaTeX file (size option) ) \c@part=\count79 \c@section=\count80 \c@subsection=\count81 \c@subsubsection=\count82 \c@paragraph=\count83 \c@subparagraph=\count84 \c@figure=\count85 \c@table=\count86 \abovecaptionskip=\skip41 \belowcaptionskip=\skip42 \bibindent=\dimen102 ) (report-refs.tex) (/usr/share/texmf/tex/plain/dvips/epsf.tex This is `epsf.tex' v2.7k <10 July 1997> \epsffilein=\read1 \epsfframemargin=\dimen103 \epsfframethickness=\dimen104 \epsfrsize=\dimen105 \epsftmp=\dimen106 \epsftsize=\dimen107 \epsfxsize=\dimen108 \epsfysize=\dimen109 \pspoints=\dimen110 \epsfnoopenhelp=\toks14 ) (haskell-tutorial.aux) \openout1 = `haskell-tutorial.aux'. LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 40. LaTeX Font Info: ... okay on input line 40. LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 40. LaTeX Font Info: ... okay on input line 40. LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 40. LaTeX Font Info: ... okay on input line 40. LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 40. LaTeX Font Info: ... okay on input line 40. LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 40. LaTeX Font Info: ... okay on input line 40. LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 40. LaTeX Font Info: ... okay on input line 40. LaTeX Font Info: External font `cmex10' loaded for size (Font) <12> on input line 56. LaTeX Font Info: External font `cmex10' loaded for size (Font) <8> on input line 56. LaTeX Font Info: External font `cmex10' loaded for size (Font) <6> on input line 56. LaTeX Font Info: Try loading font information for OMS+cmr on input line 58. (/usr/share/texmf/tex/latex/base/omscmr.fd File: omscmr.fd 1998/03/27 v2.5g Standard LaTeX font definitions ) LaTeX Font Info: Font shape `OMS/cmr/m/n' in size <10.95> not available (Font) Font shape `OMS/cmsy/m/n' tried instead on input line 58. (intro.tex [1 ] LaTeX Font Info: External font `cmex10' loaded for size (Font) <10.95> on input line 58. LaTeX Font Info: External font `cmex10' loaded for size (Font) <9> on input line 58. LaTeX Font Info: External font `cmex10' loaded for size (Font) <5> on input line 58. ) (goodies.tex [2] [3] [4] [5] Underfull \hbox (badness 10000) in paragraph at lines 287--291 [] [6] Underfull \hbox (badness 10000) in paragraph at lines 322--328 [] [7] [8] Underfull \hbox (badness 10000) in paragraph at lines 475--481 [] [9]) (functions.tex [10] Underfull \hbox (badness 10000) in paragraph at lines 102--106 [] [11] Underfull \hbox (badness 10000) in paragraph at lines 130--134 [] [12] [13] [14] Underfull \hbox (badness 10000) in paragraph at lines 334--339 [] ) (patterns.tex [15] [16] Underfull \hbox (badness 10000) in paragraph at lines 175--181 [] [17] [18] [19] [20]) (classes.tex [21] [22] [23] [24] [25] [26]) (moretypes.tex [27] Overfull \hbox (0.5705pt too wide) in paragraph at lines 64--67 \OT1/cmr/m/n/10.95 The fields within a Haskell data type can be ac-cessed ei-th er po-si-tion-ally or by name us-ing []. [] Underfull \hbox (badness 10000) in paragraph at lines 98--103 [] Overfull \hbox (2.41925pt too wide) in paragraph at lines 104--111 []\OT1/cmr/m/n/10.95 Field la-bels can also be used to con-struct new val-ues. The ex-pres-sion [] [] Underfull \hbox (badness 10000) in paragraph at lines 114--117 [] [28] [29]) (io.tex [30] [31] [32] [33] Underfull \hbox (badness 10000) in paragraph at lines 275--284 [] [34] Underfull \vbox (badness 10000) has occurred while \output is active [] [35] [36]) (stdclasses.tex [37] Overfull \hbox (1.39136pt too wide) in paragraph at lines 114--126 [] [] [38] [39] Overfull \hbox (8.55182pt too wide) detected at line 198 [] [] Underfull \hbox (badness 10000) in paragraph at lines 220--230 [] [40] Underfull \hbox (badness 10000) in paragraph at lines 292--298 [] [41]) (monads.tex [42] [43] [44] [45] [46] [47] [48] [49]) (numbers.tex [50] Underfull \hbox (badness 10000) in paragraph at lines 61--66 [] [51] Overfull \hbox (12.0541pt too wide) in paragraph at lines 79--90 []\OT1/cmr/m/n/10.95 , which re-stricts the ar-gu-ment type; thus, the stan-dar d com-plex types are [] [] Underfull \hbox (badness 10000) in paragraph at lines 90--94 [] Underfull \hbox (badness 10000) in paragraph at lines 103--107 [] Underfull \hbox (badness 10000) in paragraph at lines 120--131 [] [52] [53]) (modules.tex [54] Underfull \vbox (badness 10000) has occurred while \output is active [] [55] [56]) (pitfalls.tex [57] Underfull \hbox (badness 10000) in paragraph at lines 38--42 [] [58]) (arrays.tex [59] [60] Overfull \hbox (1.39136pt too wide) in paragraph at lines 138--149 [] [] Underfull \hbox (badness 10000) in paragraph at lines 156--162 [] [61] Underfull \hbox (badness 10000) in paragraph at lines 187--193 [] Overfull \hbox (1.39136pt too wide) in paragraph at lines 207--223 [] [] [62] Underfull \hbox (badness 10000) in paragraph at lines 223--235 [] ) (end.tex [63]) (haskell-tutorial.bbl) [64] (haskell-tutorial.aux) LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right. ) Here is how much of TeX's memory you used: 547 strings out of 10898 6424 string characters out of 96881 51436 words of memory out of 263001 3492 multiletter control sequences out of 10000+0 12152 words of font info for 42 fonts, out of 400000 for 1000 14 hyphenation exceptions out of 1000 26i,9n,19p,206b,270s stack positions out of 300i,100n,500p,50000b,4000s Output written on haskell-tutorial.dvi (64 pages, 225084 bytes). haskell-98-tutorial-sources/haskell-tutorial.aux0100644000106400000620000001673207121452210020410 0ustar jcpftp\relax \citation{haskell-98} \citation{bird98} \citation{davie92} \citation{huda89a} \citation{haskell-libs} \@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}} \newlabel{tut-intro}{{1}{1}} \@writefile{toc}{\contentsline {section}{\numberline {2}Values, Types, and Other Goodies}{2}} \newlabel{tut-values-etc}{{2}{2}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Polymorphic Types}{3}} \newlabel{tut-polymorphism}{{2.1}{3}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2}User-Defined Types}{5}} \newlabel{tut-user-types}{{2.2}{5}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.1}Recursive Types}{6}} \newlabel{tut-recursive-types}{{2.2.1}{6}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Type Synonyms}{7}} \newlabel{tut-type-synonyms}{{2.3}{7}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Built-in Types Are Not Special}{7}} \newlabel{tut-built-ins}{{2.4}{7}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {2.4.1}List Comprehensions and Arithmetic Sequences}{9}} \newlabel{tut-list-comps}{{2.4.1}{9}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {2.4.2}Strings}{10}} \newlabel{tut-strings}{{2.4.2}{10}} \@writefile{toc}{\contentsline {section}{\numberline {3}Functions}{10}} \newlabel{tut-functions}{{3}{10}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Lambda Abstractions}{11}} \newlabel{tut-lambda}{{3.1}{11}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Infix Operators}{11}} \newlabel{tut-infix-ops}{{3.2}{11}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.1}Sections}{11}} \newlabel{tut-sections}{{3.2.1}{11}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.2.2}Fixity Declarations}{12}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Functions are Non-strict}{12}} \newlabel{tut-non-strict}{{3.3}{12}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.4}``Infinite'' Data Structures}{13}} \newlabel{tut-infinite}{{3.4}{13}} \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Circular Fibonacci Sequence}}{14}} \newlabel{tut-fib-fig}{{1}{14}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.5}The Error Function}{15}} \@writefile{toc}{\contentsline {section}{\numberline {4}Case Expressions and Pattern Matching}{15}} \newlabel{tut-pattern-matching}{{4}{15}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Pattern-Matching Semantics}{16}} \newlabel{tut-matching-semantics}{{4.1}{16}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.2}An Example}{17}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Case Expressions}{17}} \newlabel{tut-case}{{4.3}{17}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Lazy Patterns}{18}} \newlabel{tut-lazy-patterns}{{4.4}{18}} \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Client-Server Simulation}}{19}} \newlabel{tut-client-fig}{{2}{19}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.5}Lexical Scoping and Nested Forms}{20}} \newlabel{tut-nesting}{{4.5}{20}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.6}Layout}{20}} \newlabel{tut-layout}{{4.6}{20}} \@writefile{toc}{\contentsline {section}{\numberline {5}Type Classes and Overloading}{21}} \newlabel{tut-type-classes}{{5}{21}} \@writefile{toc}{\contentsline {section}{\numberline {6}Types, Again}{27}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.1}The Newtype Declaration}{27}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.2}Field Labels}{28}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Strict Data Constructors}{29}} \newlabel{tut-strict-flag}{{6.3}{29}} \@writefile{toc}{\contentsline {section}{\numberline {7}Input/Output}{30}} \newlabel{tut-io}{{7}{30}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.1}Basic I/O Operations}{31}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.2}Programming With Actions}{32}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.3}Exception Handling}{33}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.4}Files, Channels, and Handles}{35}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.5}Haskell and Imperative Programming}{36}} \@writefile{toc}{\contentsline {section}{\numberline {8}Standard Haskell Classes}{37}} \@writefile{toc}{\contentsline {subsection}{\numberline {8.1}Equality and Ordered Classes}{37}} \@writefile{toc}{\contentsline {subsection}{\numberline {8.2}The Enumeration Class}{37}} \newlabel{tut-enum-classes}{{8.2}{37}} \@writefile{toc}{\contentsline {subsection}{\numberline {8.3}The Read and Show Classes}{37}} \newlabel{tut-text-class}{{8.3}{37}} \citation{wadler:list-of-successes} \@writefile{toc}{\contentsline {subsection}{\numberline {8.4}Derived Instances}{41}} \newlabel{tut-derived-instances}{{8.4}{41}} \citation{wadler:mffp} \@writefile{toc}{\contentsline {section}{\numberline {9}About Monads}{42}} \newlabel{tut-monads}{{9}{42}} \@writefile{toc}{\contentsline {subsection}{\numberline {9.1}Monadic Classes}{43}} \newlabel{tut-monadic-classes}{{9.1}{43}} \citation{wadler:mffp} \@writefile{toc}{\contentsline {subsection}{\numberline {9.2}Built-in Monads}{45}} \@writefile{toc}{\contentsline {subsection}{\numberline {9.3}Using Monads}{46}} \citation{RRRRS} \citation{steele:common-lisp} \@writefile{toc}{\contentsline {section}{\numberline {10}Numbers}{51}} \@writefile{toc}{\contentsline {subsection}{\numberline {10.1}Numeric Class Structure}{51}} \@writefile{toc}{\contentsline {subsection}{\numberline {10.2}Constructed Numbers}{52}} \@writefile{toc}{\contentsline {subsection}{\numberline {10.3}Numeric Coercions and Overloaded Literals}{52}} \newlabel{tut-num-constants}{{10.3}{52}} \@writefile{toc}{\contentsline {subsection}{\numberline {10.4}Default Numeric Types}{53}} \@writefile{toc}{\contentsline {section}{\numberline {11}Modules}{54}} \newlabel{tut-modules}{{11}{54}} \@writefile{toc}{\contentsline {subsection}{\numberline {11.1}Qualified Names}{55}} \@writefile{toc}{\contentsline {subsection}{\numberline {11.2}Abstract Data Types}{56}} \newlabel{tut-ADTs}{{11.2}{56}} \@writefile{toc}{\contentsline {subsection}{\numberline {11.3}More Features}{57}} \newlabel{tut-rules}{{11.3}{57}} \@writefile{toc}{\contentsline {section}{\numberline {12}Typing Pitfalls}{57}} \@writefile{toc}{\contentsline {subsection}{\numberline {12.1}Let-Bound Polymorphism}{58}} \@writefile{toc}{\contentsline {subsection}{\numberline {12.2}Numeric Overloading}{58}} \@writefile{toc}{\contentsline {subsection}{\numberline {12.3}The Monomorphism Restriction}{58}} \@writefile{toc}{\contentsline {section}{\numberline {13}Arrays}{59}} \@writefile{toc}{\contentsline {subsection}{\numberline {13.1}Index types}{59}} \citation{id-manual} \@writefile{toc}{\contentsline {subsection}{\numberline {13.2}Array Creation}{60}} \@writefile{toc}{\contentsline {subsection}{\numberline {13.3}Accumulation}{61}} \@writefile{toc}{\contentsline {subsection}{\numberline {13.4}Incremental updates}{62}} \@writefile{toc}{\contentsline {subsection}{\numberline {13.5}An example: Matrix Multiplication}{62}} \bibstyle{plain} \bibdata{tut} \bibcite{bird98}{1} \bibcite{davie92}{2} \bibcite{huda89a}{3} \bibcite{haskell-98}{4} \bibcite{haskell-libs}{5} \bibcite{id-manual}{6} \bibcite{RRRRS}{7} \bibcite{steele:common-lisp}{8} \bibcite{wadler:list-of-successes}{9} \bibcite{wadler:mffp}{10} \@writefile{toc}{\contentsline {section}{\numberline {14}The Next Stage}{64}} \@writefile{toc}{\contentsline {section}{\numberline {15}Acknowledgements}{64}} haskell-98-tutorial-sources/tutrefs0100644000106400000620000000407407121453057016032 0ustar jcpftp$wadler:mffp=haskell-tutorial $wadler:list-of-successes=haskell-tutorial $steele:common-lisp=haskell-tutorial $RRRRS=haskell-tutorial $id-manual=haskell-tutorial $haskell-libs=haskell-tutorial $haskell-98=haskell-tutorial $huda89a=haskell-tutorial $davie92=haskell-tutorial $bird98=haskell-tutorial sect15=end sect14=end sect13.5=arrays sect13.4=arrays sect13.3=arrays sect13.2=arrays sect13.1=arrays sect13=arrays sect12.3=pitfalls sect12.2=pitfalls sect12.1=pitfalls sect12=pitfalls tut-rules=modules sect11.3=modules tut-ADTs=modules sect11.2=modules sect11.1=modules tut-modules=modules sect11=modules sect10.4=numbers tut-num-constants=numbers sect10.3=numbers sect10.2=numbers sect10.1=numbers sect10=numbers sect9.3=monads sect9.2=monads tut-monadic-classes=monads sect9.1=monads tut-monads=monads sect9=monads tut-derived-instances=stdclasses sect8.4=stdclasses tut-text-class=stdclasses sect8.3=stdclasses tut-enum-classes=stdclasses sect8.2=stdclasses sect8.1=stdclasses sect8=stdclasses sect7.5=io sect7.4=io sect7.3=io sect7.2=io sect7.1=io tut-io=io sect7=io tut-strict-flag=moretypes sect6.3=moretypes sect6.2=moretypes sect6.1=moretypes sect6=moretypes tut-type-classes=classes sect5=classes tut-layout=patterns sect4.6=patterns tut-nesting=patterns sect4.5=patterns tut-lazy-patterns=patterns sect4.4=patterns tut-case=patterns sect4.3=patterns sect4.2=patterns tut-matching-semantics=patterns sect4.1=patterns tut-pattern-matching=patterns sect4=patterns sect3.5=functions tut-infinite=functions sect3.4=functions tut-non-strict=functions sect3.3=functions sect3.2.2=functions tut-sections=functions sect3.2.1=functions tut-infix-ops=functions sect3.2=functions tut-lambda=functions sect3.1=functions tut-functions=functions sect3=functions tut-strings=goodies sect2.4.2=goodies tut-list-comps=goodies sect2.4.1=goodies tut-built-ins=goodies sect2.4=goodies tut-type-synonyms=goodies sect2.3=goodies tut-recursive-types=goodies sect2.2.1=goodies tut-user-types=goodies sect2.2=goodies tut-polymorphism=goodies sect2.1=goodies tut-values-etc=goodies sect2=goodies tut-intro=intro sect1=intro haskell-98-tutorial-sources/haskell.aux0100644000106400000620000004542307121450110016543 0ustar jcpftp\relax \citation{curry&feys:book} \@writefile{toc}{\contentsline {subsection}{\numberline {0.1}Goals}{v}} \citation{tutorial} \citation{libraries} \@writefile{toc}{\contentsline {subsection}{\numberline {0.2}Haskell 98}{vi}} \@writefile{toc}{\contentsline {subsection}{\numberline {0.3}This Report}{vi}} \@writefile{toc}{\contentsline {subsection}{\numberline {0.4}Evolutionary Highlights}{vi}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {0.4.1}Highlights of Haskell 98}{vi}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {0.4.2}Highlights of Haskell 1.4}{vii}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {0.4.3}Highlights of Haskell 1.3}{vii}} \@writefile{toc}{\contentsline {subsection}{\numberline {0.5}The \unhbox \voidb@x \hbox {$\it n+k$} Pattern Controversy}{viii}} \@writefile{toc}{\contentsline {subsection}{\numberline {0.6}Haskell{} Resources}{viii}} \citation{back78} \@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}} \newlabel{introduction}{{1}{1}} \@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Program Structure}{1}} \newlabel{programs}{{1.1}{1}} \@writefile{toc}{\contentsline {subsection}{\numberline {1.2}The Haskell{} Kernel}{2}} \newlabel{intro-kernel}{{1.2}{2}} \@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Values and Types}{2}} \newlabel{errors}{{1.3}{2}} \@writefile{toc}{\contentsline {subsection}{\numberline {1.4}Namespaces}{2}} \newlabel{namespaces}{{1.4}{2}} \citation{unicode} \@writefile{toc}{\contentsline {section}{\numberline {2}Lexical Structure}{4}} \newlabel{lexical-structure}{{2}{4}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Notational Conventions}{4}} \newlabel{notational-conventions}{{2.1}{4}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Lexical Program Structure}{5}} \newlabel{lexemes}{{2.2}{5}} \newlabel{whitespace}{{2.2}{5}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Comments}{6}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Identifiers and Operators}{6}} \newlabel{ids}{{2.4}{6}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Numeric Literals}{8}} \newlabel{lexemes-numeric}{{2.5}{8}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Character and String Literals}{9}} \newlabel{lexemes-char}{{2.6}{9}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.7}Layout}{10}} \newlabel{lexemes-layout}{{2.7}{10}} \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces A sample program}}{11}} \newlabel{layout-before}{{1}{11}} \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Sample program with layout expanded}}{11}} \newlabel{layout-after}{{2}{11}} \@writefile{toc}{\contentsline {section}{\numberline {3}Expressions}{12}} \newlabel{expressions}{{3}{12}} \@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Precedence of expressions, patterns, definitions (highest to lowest)}}{13}} \newlabel{syntax-precedences}{{1}{13}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Errors}{14}} \newlabel{basic-errors}{{3.1}{14}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Variables, Constructors, Operators, and Literals}{14}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Curried Applications and Lambda Abstractions}{16}} \newlabel{applications}{{3.3}{16}} \newlabel{lambda-abstractions}{{3.3}{16}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Operator Applications}{16}} \newlabel{operators}{{3.4}{16}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Sections}{17}} \newlabel{sections}{{3.5}{17}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Conditionals}{18}} \newlabel{conditionals}{{3.6}{18}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Lists}{18}} \newlabel{lists}{{3.7}{18}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.8}Tuples}{19}} \newlabel{tuples}{{3.8}{19}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.9}Unit Expressions and Parenthesized Expressions}{19}} \newlabel{unit-expression}{{3.9}{19}} \@writefile{toc}{\contentsline {paragraph}{Translation:}{19}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.10}Arithmetic Sequences}{19}} \newlabel{arithmetic-sequences}{{3.10}{19}} \@writefile{toc}{\contentsline {paragraph}{Translation:}{20}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.11}List Comprehensions}{21}} \newlabel{list-comprehensions}{{3.11}{21}} \@writefile{toc}{\contentsline {paragraph}{Translation:}{21}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.12}Let Expressions}{22}} \newlabel{let-expressions}{{3.12}{22}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.13}Case Expressions}{22}} \newlabel{case}{{3.13}{22}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.14}Do Expressions}{23}} \newlabel{do-expressions}{{3.14}{23}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.15}Datatypes with Field Labels}{24}} \newlabel{field-ops}{{3.15}{24}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.15.1}Field Selection}{25}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.15.2}Construction Using Field Labels}{25}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.15.3}Updates Using Field Labels}{26}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.16}Expression Type-Signatures}{27}} \newlabel{expression-type-sigs}{{3.16}{27}} \@writefile{toc}{\contentsline {subsection}{\numberline {3.17}Pattern Matching}{27}} \newlabel{pattern-matching}{{3.17}{27}} \newlabel{patterns}{{3.17}{27}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.17.1}Patterns}{27}} \newlabel{pattern-definitions}{{3.17.1}{27}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.17.2}Informal Semantics of Pattern Matching}{29}} \@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Semantics of Case Expressions, Part 1}}{31}} \newlabel{simple-case-expr-1}{{3}{31}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.17.3}Formal Semantics of Pattern Matching}{32}} \newlabel{case-semantics}{{3.17.3}{32}} \@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Semantics of Case Expressions, Part 2}}{33}} \newlabel{simple-case-expr-2}{{4}{33}} \@writefile{toc}{\contentsline {section}{\numberline {4}Declarations and Bindings}{34}} \newlabel{declarations}{{4}{34}} \citation{damas-milner82} \citation{hindley69} \citation{jones:cclasses} \citation{wadler:classes} \@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Overview of Types and Classes}{35}} \newlabel{types-overview}{{4.1}{35}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.1}Kinds}{36}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.2}Syntax of Types}{36}} \newlabel{type-syntax}{{4.1.2}{36}} \newlabel{types}{{4.1.2}{36}} \citation{damas-milner82} \citation{wadler:classes} \citation{jones:cclasses} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.3}Syntax of Class Assertions and Contexts}{38}} \newlabel{classes&contexts}{{4.1.3}{38}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.4}Semantics of Types and Classes}{38}} \newlabel{type-semantics}{{4.1.4}{38}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.2}User-Defined Datatypes}{39}} \newlabel{user-defined-datatypes}{{4.2}{39}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.1}Algebraic Datatype Declarations}{40}} \newlabel{datatype-decls}{{4.2.1}{40}} \newlabel{field-labels}{{4.2.1}{41}} \@writefile{toc}{\contentsline {paragraph}{Labelled Fields}{41}} \newlabel{strictness-flags}{{4.2.1}{41}} \@writefile{toc}{\contentsline {paragraph}{Strictness Flags}{41}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.2}Type Synonym Declarations}{42}} \newlabel{type-synonym-decls}{{4.2.2}{42}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.3}Datatype Renamings}{43}} \newlabel{datatype-renaming}{{4.2.3}{43}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Type Classes and Overloading}{44}} \newlabel{overloading}{{4.3}{44}} \newlabel{classes}{{4.3}{44}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.1}Class Declarations}{44}} \newlabel{class-decls}{{4.3.1}{44}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.2}Instance Declarations}{45}} \newlabel{instance-decls}{{4.3.2}{45}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.3}Derived Instances}{48}} \newlabel{derived-decls}{{4.3.3}{48}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.4}Ambiguous Types, and Defaults for Overloaded Numeric Operations}{48}} \newlabel{default-decls}{{4.3.4}{48}} \@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Nested Declarations}{49}} \newlabel{nested}{{4.4}{49}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.1}Type Signatures}{50}} \newlabel{type-signatures}{{4.4.1}{50}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.2}Fixity Declarations}{51}} \newlabel{fixity}{{4.4.2}{51}} \@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Precedences and fixities of prelude operators}}{52}} \newlabel{prelude-fixities}{{2}{52}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.4.3}Function and Pattern Bindings}{52}} \newlabel{function-bindings}{{4.4.3}{52}} \newlabel{pattern-bindings}{{4.4.3}{52}} \newlabel{patbind}{{4.4.3}{54}} \citation{peyton-jones:book} \@writefile{toc}{\contentsline {subsection}{\numberline {4.5}Static Semantics of Function and Pattern Bindings}{55}} \newlabel{dependencyanalysis}{{4.5}{55}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.1}Dependency Analysis}{55}} \newlabel{depend-anal}{{4.5.1}{55}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.2}Generalization}{55}} \newlabel{generalization}{{4.5.2}{55}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.3}Context Reduction Errors}{56}} \newlabel{context-reduction}{{4.5.3}{56}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.4}Monomorphism}{57}} \newlabel{monomorphism}{{4.5.4}{57}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {4.5.5}The Monomorphism Restriction}{58}} \newlabel{sect:monomorphism-restriction}{{4.5.5}{58}} \citation{jones:cclasses} \@writefile{toc}{\contentsline {subsection}{\numberline {4.6}Kind Inference}{60}} \newlabel{kindinference}{{4.6}{60}} \citation{libraries} \@writefile{toc}{\contentsline {section}{\numberline {5}Modules}{62}} \newlabel{modules}{{5}{62}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Module Structure}{63}} \newlabel{module-implementations}{{5.1}{63}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Export Lists}{63}} \newlabel{export}{{5.2}{63}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Import Declarations}{65}} \newlabel{import}{{5.3}{65}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.1}Qualified import}{66}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.3.2}Local aliases}{67}} \newlabel{as-clause}{{5.3.2}{67}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Importing and Exporting Instance Declarations}{67}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.5}Name Clashes and Closure}{68}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.1}Qualified names}{68}} \newlabel{qualifiers}{{5.5.1}{68}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.2}Name clashes}{68}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.5.3}Closure}{69}} \newlabel{closure}{{5.5.3}{69}} \citation{libraries} \@writefile{toc}{\contentsline {subsection}{\numberline {5.6}Standard Prelude}{70}} \newlabel{standard-prelude}{{5.6}{70}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.1}The \unhbox \voidb@x \hbox {\tt Prelude} Module}{71}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {5.6.2}Shadowing Prelude Names}{71}} \newlabel{std-prel-shadowing}{{5.6.2}{71}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.7}Separate Compilation}{72}} \@writefile{toc}{\contentsline {subsection}{\numberline {5.8}Abstract Datatypes}{72}} \newlabel{abstract-types}{{5.8}{72}} \citation{unicode} \@writefile{toc}{\contentsline {section}{\numberline {6}Predefined Types and Classes}{73}} \newlabel{basic-types-and-classes}{{6}{73}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.1}Standard Haskell Types}{73}} \newlabel{basic-types}{{6.1}{73}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.1}Booleans}{73}} \newlabel{booleans}{{6.1.1}{73}} \newlabel{prelude-bool}{{6.1.1}{73}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.2}Characters and Strings}{73}} \newlabel{characters}{{6.1.2}{73}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.3}Lists}{74}} \newlabel{basic-lists}{{6.1.3}{74}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.4}Tuples}{74}} \newlabel{basic-tuples}{{6.1.4}{74}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.5}The Unit Datatype}{74}} \newlabel{basic-trivial}{{6.1.5}{74}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.6}Function Types}{74}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.7}The IO and IOError Types}{75}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.1.8}Other Types}{75}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.2}Strict Evaluation}{75}} \newlabel{strict-eval}{{6.2}{75}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.3}Standard Haskell Classes}{76}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.1}The Eq Class}{76}} \@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Standard Haskell Classes}}{77}} \newlabel{standard-classes}{{5}{77}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.2}The Ord Class}{78}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.3}The Read and Show Classes}{78}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.4}The Enum Class}{79}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.5}Class \unhbox \voidb@x \hbox {\tt Functor}}{80}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.6}Class \unhbox \voidb@x \hbox {\tt Monad}}{80}} \newlabel{monad-class}{{6.3.6}{80}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.3.7}The Bounded Class}{81}} \@writefile{toc}{\contentsline {subsection}{\numberline {6.4}Numbers}{81}} \newlabel{numbers}{{6.4}{81}} \@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces Standard Numeric Types}}{82}} \newlabel{standard-numeric-types}{{3}{82}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.1}Numeric Literals}{82}} \newlabel{numeric-literals}{{6.4.1}{82}} \@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Standard Numeric Classes and Related Operations, Part 1}}{83}} \newlabel{basic-numeric-1}{{6}{83}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.2}Arithmetic and Number-Theoretic Operations}{83}} \newlabel{arithmetic-operators}{{6.4.2}{83}} \@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Standard Numeric Classes and Related Operations, Part 2}}{84}} \newlabel{basic-numeric-2}{{7}{84}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.3}Exponentiation and Logarithms}{84}} \citation{penfield:complex-apl} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.4}Magnitude and Sign}{85}} \newlabel{magnitude-sign}{{6.4.4}{85}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.5}Trigonometric Functions}{85}} \@writefile{toc}{\contentsline {subsubsection}{\numberline {6.4.6}Coercions and Component Extraction}{85}} \newlabel{coercion}{{6.4.6}{85}} \@writefile{toc}{\contentsline {section}{\numberline {7}Basic Input/Output}{87}} \newlabel{io}{{7}{87}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.1}Standard I/O Functions}{87}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.2}Sequencing I/O Operations}{89}} \@writefile{toc}{\contentsline {subsection}{\numberline {7.3}Exception Handling in the I/O Monad}{90}} \@writefile{toc}{\contentsline {section}{\numberline {A}Standard Prelude}{91}} \newlabel{stdprelude}{{A}{91}} \@writefile{toc}{\contentsline {subsection}{\numberline {A.1}Prelude {\tt PreludeList}}{105}} \newlabel{preludelist}{{A.1}{105}} \@writefile{toc}{\contentsline {subsection}{\numberline {A.2}Prelude {\tt PreludeText}}{112}} \newlabel{preludetext}{{A.2}{112}} \@writefile{toc}{\contentsline {subsection}{\numberline {A.3}Prelude {\tt PreludeIO}}{117}} \newlabel{preludeio}{{A.3}{117}} \@writefile{toc}{\contentsline {section}{\numberline {B}Syntax}{119}} \newlabel{syntax}{{B}{119}} \@writefile{toc}{\contentsline {subsection}{\numberline {B.1}Notational Conventions}{119}} \@writefile{toc}{\contentsline {subsection}{\numberline {B.2}Lexical Syntax}{119}} \@writefile{toc}{\contentsline {subsection}{\numberline {B.3}Layout}{122}} \newlabel{layout}{{B.3}{122}} \@writefile{toc}{\contentsline {subsection}{\numberline {B.4}Context-Free Syntax}{125}} \newlabel{bnf}{{B.4}{125}} \@writefile{toc}{\contentsline {section}{\numberline {C}Literate comments}{130}} \newlabel{literate}{{C}{130}} \@writefile{toc}{\contentsline {section}{\numberline {D}Specification of Derived Instances}{132}} \newlabel{derived-appendix}{{D}{132}} \@writefile{toc}{\contentsline {subsection}{\numberline {D.1}Derived instances of \unhbox \voidb@x \hbox {\tt Eq} and \unhbox \voidb@x \hbox {\tt Ord}.}{133}} \@writefile{toc}{\contentsline {subsection}{\numberline {D.2}Derived instances of \unhbox \voidb@x \hbox {\tt Enum}}{133}} \@writefile{toc}{\contentsline {subsection}{\numberline {D.3}Derived instances of \unhbox \voidb@x \hbox {\tt Bounded}.}{134}} \@writefile{toc}{\contentsline {subsection}{\numberline {D.4}Derived instances of \unhbox \voidb@x \hbox {\tt Read} and \unhbox \voidb@x \hbox {\tt Show}.}{134}} \@writefile{toc}{\contentsline {subsection}{\numberline {D.5}An Example}{136}} \@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Example of Derived Instances}}{137}} \newlabel{tree-inst}{{8}{137}} \@writefile{toc}{\contentsline {section}{\numberline {E}Compiler Pragmas}{138}} \newlabel{pragmas}{{E}{138}} \@writefile{toc}{\contentsline {subsection}{\numberline {E.1}Inlining}{138}} \@writefile{toc}{\contentsline {subsection}{\numberline {E.2}Specialization}{138}} \@writefile{toc}{\contentsline {subsection}{\numberline {E.3}Optimization}{139}} \bibstyle{plain} \bibdata{haskell} \bibcite{back78}{1} \bibcite{curry&feys:book}{2} \bibcite{damas-milner82}{3} \bibcite{hindley69}{4} \bibcite{tutorial}{5} \bibcite{jones:cclasses}{6} \bibcite{penfield:complex-apl}{7} \bibcite{libraries}{8} \bibcite{peyton-jones:book}{9} \bibcite{unicode}{10} \bibcite{wadler:classes}{11} \@writefile{toc}{\contentsline {section}{References}{141}} \citation{libraries} \@writefile{toc}{\contentsline {section}{Index}{143}}