Content

Haskell is a pure functional programming language. Two free wellknown haskell compilers are availbale on the intranet:
Some references to learn the language:
To answer this question we first look at a function.
A function is a transformation of input data (arguments) to output data.
A computer progam consists of a collection of functions. Each function within a computer program can be a highlevel or primitive function. A primitive function is a function that can be uniquely mapped by the compiler to a CPU instruction. A CPU instruction is the ultimate transformation step that can be applied to data in the memory of a computer.
It is only the data in the memory of a computer that we can transform and we transform it by applying a function to this data. All computer languages have predefined primitive functions, like mathematical operators, such as: add (+),subtract (),multiply (*), divide (/), boolean operators. Only these primitive functions can change the data in the computer memory. A computer program consists of user defined functions that apply the primitive functions to data in the memory of the computer. However specifying the data transformation is only one aspect of a computer program another as important aspect is the sequence of instructions. This sequence of instructions is called the control flow. It allows the programmer to specify the flow of the transformations by branching and jumping (if .. then .. else) and repetition (loop). Next the computer language must also be able to assign to a certain location in the computer memory a value and to move data in and out of the computer memory to other devices (screen, printer, network,...). So, any computer language must specify in a certain way these type of actions: assiging data, modifying data, branching and looping, and transferring data.
For the design of a computer language different methodologies have been followed. The traditional approach, imperative languages, define the data to be used, and then the functions to transform this data. Functional programming languages define only functions. That is the main difference.
To show the difference in approach between an imperative and function language we take a look at a simple function that sums n the first n integers. Here is the imperative variant of such a function:
and here the functional variantNote that in a functional language we do not define the variables list, n and s. A lot of code in an imperative language is used to define variables and updating the value of these variables. However as functional languages show we could specify the same function with less detail, and let the computer figure out (by the compiler) how to complete the specified task. The functional langauge gives a more 'mathematically' definition of what a sum really means. First it says that the sum of nothing, the empty list, is zero. Then for the other cases the sum is the addition of the first element to the sum of the remaining elements. This is a recursive definition. So the computer can now iterate through the list without the need for the programmer to define this low level iteration process. You also notice that the syntax is far more concise, no curly braces, no semicolon to end a statement. It is an elegant way of programming which focus more on defining concepts and less on the sequential steps to perform mechanical calculations.
We assume the Hugs system is used. The Hugs system is an interactive environment. Commands and Haskell instructions are typed at the the command prompt $>$. To see the build in commands type :?. Any command can be started by its first letter. During startup the Hugs systems loads prelude.hs. This module defines a number of basic functions, type :names to see the list of functions or open prelude.hs in a text editor.
Haskell defines the standard operations on numbers:
These operators follow the normal precedence rules. With parentheses (,) this order can be overruled or shown explicitly. The operators can be called also in prefix notation: (+) a b
Haskell has many standard functions which operate on lists: head, tail, length, take, drop, sum and many more. A list argument has by convention an s as suffix, e.g. a list of numbers: ns, a list of arbitrary values: xs and a list of characters: cs.
The following list of keywords can not be used as function names:
A function definition is defined in a text file with .hs as file extension. The file is loaded or after changing reloaded in the Hugs environment with the commands :load and :reload. Function names start with a small letter. A function in mathematics is denoted by $f(a,b,c)$ whereas in Haskell this is denoted by $f a\:b\:c$. A composition of functions in mathematics is denoted by $f(a,g(b))$ and in Haskell by $f \:a \:(g\:x)$.
A function definition relies on a layout rule: the elements of a function definition at the same level are aligned in the same column and different levels are indicated by indention.
Comments on one line start with  and comments over multiple lines are enclosed between { and }.
A type is a collection of related values. We use the notation $v :: T$ to denote that $v$ is a value of type $T$ and $f:T_1 \rightarrow T_2$ to denote that $f$ is a function transforming values of $T_1$ to values of $T_2$ and $e::T$ to denote that the expression $e$ result in a value of type $T$. In Haskell, every expression must have a type, which is calculated prior to evaluating the expression by a process called type inference. \[ \frac{f::A \rightarrow B \;\;\; e::A}{f \;\; e::B} \] If a proper type can not be derived, the expression is in error. Haskell is type safe because type inference precedes evaluation.
Function 
Type 
Comment 
:  a > [a] > [a]  (infix) Add an element to the front of the list 
++  [a] > [a] > [a]  (infix) Append two lists 
!!  [a] > Int > a  (infix) Return element Int of the list, counting from zero 
head  [a] > a  Return the first element of the list 
tail  [a] > [a]  Return the list with the first element removed 
last  [a] > a  Return the last element in the list 
init  [a] > [a]  Return the list with the last element removed 
reverse  [a] > [a]  Return the list with the elements in reverse order 
take  Int > [a] > [a]  Return the first Int elements of the list 
drop  Int > [a] > [a]  Return the list with the first Int elements removed 
nub  [a] > [a]  Return the list with all duplicate elements removed 
elem notElem  [a] > a > Bool  Test for membership in the list 
length  [a] > Int  The number of elements in the list 
concat  [[a]] > [a]  Given a list of lists, concatenate all the lists into one list 
Notation 
Explanation 
Example 
[a..b]  A list of integers from a to b  [1..5]=[1,2,3,4,5] 
[a..]  A list of integers >=a  [1..] all positive integers 
[a,b..c]  A list starting at a with step ba and up till <=c  [1,3..10]=[1,3,5,7,9] 
[a,b..]  A list of integers from a with step ba  [1,3..] all positive odd numbers 
[ exp_x  x <list]  A list of values of the expression with x drawn from list  [x^2  x <[1,..]] list of squares of positive integers 
[ exp_x  x <list, y<list]  A list of values of the expression with x and y drawn from two lists  [[x,y]  x<['a'..'b'], y<['x'..'z']] 
[ exp_x_y  x <list, y<list]  A list of values of the expression with x and y drawn from two lists  [[x,y]  x<['a'..'b'], y<['x'..'z']] 
[ exp_x  x <list, condition_x]  A list of values of the expression with x drawn from a list and for which condition is true  [ x^2  x<[1..10], even x] = [4,16,36,64,100] 
[ exp_x_y  x <list,condition_x, y<list, condition_y]  A list of values of the expression with x and y drawn from two lists and with condition on x and y  [x+y  x<[1..5], even x, y<[1..5], odd y]=[3,5,7,5,7,9] 
A function definition consists of a name, arguments and expressions containing these arguments. Expressions are evaluated to values of a certain type. A function is nothing more than the value to which the related expression evaluates. Functions in Haskell can be treated in the same way as any other value.
The expression on the right of the equals sign indicates an (anonymous) function of two arguments, x and y, with the body of the function following the arrow; this function is "assigned to" the identifier on the left of the equals sign. (The backslash in this expression is pronounced "lambda.") Anonymous functions are used frequently in Haskell, usually surrounded by parentheses. A more compact notation is:
Athough it looks that averageof2 is a function with two arguments this is just an illusion. It consists of two anonymous functions: \x and \y. Application of this function:
So all Haskell functions are in fact single argument functions, the function operator > has a right to left association and the function application on the arguments a left to right association.
There are several mechanisms to choose which part of a function body should be executed depending on the parameters of the function.The following are patterns: literals, [], _, if p1 and p2 are different patterns then also p1:p2, if p1..pn are different patterns then also (p1,...,pn) is a pattern. The same identifier must not come more than once in a pattern, so (x,x) is not a valid pattern in Haskell.
The two equations for the definition of length are exhaustive for lists, so for any list the concept of length is defined.
A function can also be defined by one equation and different branches defined by so called guards.
using otherwise informs Haskell that the braching is exhaustive. If a function branching is not exhaustive an exception is generated when the arguments can not be matched with any pattern. The compiler warns the programmer for nonexhaustive patterns if the following option is set:
> :set fwarnincompletepatterns
If patterns are overlapping then Haskell applies the following rule: when multiple equations apply, the one that occurs first (from top to bottom) is the one chosen.
Another construct with patterns are ascriptions. An ascription is a reference to the matched pattern.
Instead of using build in types like Bool, Int, Float, Double, Char, Maybe, one can define its own types. Defining types is often usefull to make the code more human readable and to avoid that we perform incompatible operations, like adding apples and peers. There are different ways to define a type.
The name of the data type is left of the =sign. The parts after the =sign are value constructors. Multiple value constructors are separated by  (or). Both the type name and the value constructors have to be capital cased. A value constructor is a function that returns a ultimately a value of te data type. The value constructor can take therefore parameters like functions.The data type itself can also take parameter(s), we call it a type constructor.
Maybe is a type, but depending on whether or not it receives another type as a parameter it will return Nothing or Maybe a. We usually use type parameters when the type that's contained inside the data type's various value constructors isn't really that important for the type to work. With the type parameter we give some flexibility to the use of the type.
Especially when there are a large number of value constructors the record syntax can be usefull. Instead of:
following record syntax is much easier to read and use: The resulting data type is exactly the same. The main benefit of this is that it creates functions that lookup fields in the data type. We don't have to necessarily put the fields in the proper order, as long as we list all of them in creating a new value.Another thing we need in working with types are generic functions that apply the same kind of behavior to differtent types. For each type the same function name can be used, but each type has its own implementation of the functionality. Haskell solves this with a typeclass. A typeclass is a sort of interface that defines some behavior. If a type is a part of a typeclass, that means that it supports and implements the behavior the typeclass describes. Haskell has a predefined a number of typeclasses. For many simple data types, the Haskell compiler can automatically derive instances of the following typeclasses: Read, Show, Bounded, Enum, Eq, and Ord for your own defined types.
Typeclasses are not equivalent to the concept of a class in OOP.
Let us take a look at the type signature of the function (==) which tests for equality (or we could also use the negation /=):
We see left of => the type class constraint, in this case (==) is a binary function that can be applied to two values of the same type and the type must belong to the typeclass Eq, the function returns a value of type Bool. We give now some examples of apply the generic functions belonging to the standard typeclasses: Eq,Show,Read,Ord:Another example of a function with multiple class constraints is fromIntegral.
This function is used to convert an integral type to a more general number type.Avoid using type constraints in the definition of a new type. Because we don't benefit a lot, but we end up writing more class constraints for functions using this type, even when we don't need them.
We can define typeclasses ourselves. This is how the Eq class is defined in the standard prelude:
a is a type that is an instance of the typeclass Eq. In the typeclass we define the type of the functions belonging to the typeclass. We can also define these functions in the typeclass. In this case we have defined them in terms of mutual recursion. That way instances need only to define one of them.Let us bnow define a new type:
and make this type an instance of the typeclass Eq:You can also make typeclasses that are subclasses of other typeclasses. The class declaration for Num is a bit long, but here's the first part:
We state that our type a must be an instance of Eq.That's all there is to subclassing really, it's just a class constraint on a class declaration.Let us see another example of an instance declaration for Maybe. Note that Maybe is a type constructor, so Maybe m is a concrete type which can be defined as an instance of a typeclass.
we have to define a class constraint on m. We want all types of the form Maybe m to be part of the Eq typeclass, but only those types where the m (so what's contained inside the Maybe) is also a part of Eq. Most of the times, class constraints in class declarations are used for making a typeclass a subclass of another typeclass and class constraints in instance declarations are used to express requirements about the contents of some type.To see the instances of a typeclass type: :info YourTypeClass, or to see the typeclasses of a type or type constructor use :info YourType.