Getting started with Haskell
This document was adpated from the Hugs 98 User Manual.
There is an Eclispe plugin that supports Hugs. If you prefer not to use it, this document describes the native Hugs interface.
Download Hugs
Go to the download site and download WinHugs-Sep2006.exe for Windows platforms, or the sole option available there for other platforms.
Hugs for Beginners
To run from the start menu, select Hugs98 and then Hugs (Hugs mode).
(You can also start the interpreter by double clicking on a .hs or .lhs file.)
Starting the interpreter produces a startup banner something like the following.
__ __ __ __ ____ ___ _________________________________________
|| || || || || || ||__ Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__|| __|| Copyright (c) 1994-2005
||---|| ___|| World Wide Web: http://haskell.org/hugs
|| || Report bugs to: hugs-bugs@haskell.org
|| || Version: May 2006 _________________________________________
Haskell 98 mode: Restart with command line option -98 to enable extensions
Type :? for help
Hugs>
Expressions
In essence, using Hugs is just like using a calculator; the interpreter simply evaluates each expression that is entered, printing the results as it goes.
Hugs> (2+3)*8 40 Hugs> sum [1..10] 55 Hugs>
The Hugs> prompt indicates that the system is ready
to accept input from the user. By default, you have access to the
Haskell Prelude. The Prelude is a special module that
contains definitions for the built-in operations of Haskell, such as
+, *, and sum. In response to
the first prompt, the user entered the expression
(2+3)*8, which was evaluated to produce the result 40.
In response to the second prompt, the user typed the expression
sum [1..10]. The notation [1..10]
represents the list of integers between 1 and 10 inclusive, and
sum is a Prelude function that calculates the sum of a
list of numbers.
So the result obtained by Hugs is:
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55.
In fact, we could have typed this sum directly into Hugs:
Hugs> 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
55
Hugs>
Unlike many calculators, however, Hugs is not limited to working with numbers; expressions can involve many different types of value, including numbers, booleans, characters, strings, lists, functions, and user-defined datatypes.
Some of these are illustrated in the following example:
Hugs> (not True) || False
False
Hugs> reverse "Hugs is cool"
"looc si sguH"
Hugs> filter even [1..10]
[2, 4, 6, 8, 10]
Hugs even allows whole programs to be used as values in calculations.
For example, putStr "hello, " is a simple program that
outputs the string "hello, ". Combining this with a
similar program to print the string "world" gives:
Hugs> putStr "hello, " >> putStr "world"
hello, world
Hugs>
Just as there are standard operations for dealing with numbers, so
there are standard operations for dealing with programs. For example,
the >> operator used here constructs a new program from the
programs supplied as its operands, running one after the other.
Normally, Hugs just prints the value of each expression entered. But,
as this example shows, if the expression evaluates to a program, then
Hugs will run the program. Hugs distinguishes programs from other
expressions by looking at the type of the expression entered. For
example, the expression putStr "world" has type IO
(), which identifies it as a program to be executed rather
than a value to be printed.
Commands
Each line that you enter in response to the Hugs prompt is treated as a command to the interpreter. For example, when you enter an expression into Hugs, it is treated as a command to evaluate that expression, and to display the result. There are two commands that are particularly worth remembering:
- :q exits the interpreter. On most systems, you can also terminate Hugs by typing the end-of-file character (usually Ctrl-D on Unix platforms and Ctrl-Z on Windows).
- :? prints a list of all the commands
Like most other commands in Hugs, these commands both start with a
colon, :.
Note that the interrupt key (control-C or control-Break on most
systems) can be used to abandon the process of compiling files or
evaluating expressions. When the interrupt is detected, Hugs prints
{Interrupted!} and returns to the prompt so that further
commands can be entered.
Programs
Functions like sum, >> and
take, used in the examples above, are all defined in the
Hugs prelude; you can actually do quite a lot using just the types and
operations provided by the prelude. But, in general, you will also
want to define new types and operations, storing them in modules that
can be loaded and used by Hugs. A module is simply a collection of
definitions stored in a file.
You can generate a file from within the Hugs environment. Just type :edit filename.hs from the Hugs prompt. An editor will be opened for you and Hugs even remembers where it puts the file (so a full pathname is not needed). For this example, create a program called fact.hs. Enter the following lines in this file:
module Fact where fact :: Integer -> Integer fact n = product [1..n]
The meaning of these lines is as follows:
module Fact where -- module is a keyword. Fact is the name of the -- module. Module names must be capitalized. -- If there is no module name, it defaults to Main. fact :: Integer -> Integer -- Indicates that the fact function takes on Integer -- parameter and returns an Integer. The notation -- is similar to the mathematical notation for -- expressing domain and range. fact n = product [1..n] -- Indicates that the name of the parameter is n, -- and computes the result using the builtin -- product function.
By convention, Hugs modules are stored in files whose names end with .hs. The file name should match the name of the module it contains.
Save the file and exit the editor. From within hugs, type :load fact.hs.
Other choices for editing or loading a file
- You can use a provided file as a starting point. You must load it
using a complete path name such as
:load C:\me\Class\cs4700\Haskell\fact.hs
Luckily for you, the system remembers the path name during the session, so you can re-edit the file without typing in the whole name every time. Note, too, that you can get to a previously entered line in the interpreter by pressing the up arrow key. - You can use a text editor to create the file outside of the Hugs environment, and then load it (as described above).
After loading fact.hs, the prompt is now
Fact>, and evaluation takes place within this new
module. We can use the fact function we defined:
Fact> fact 6 720 Fact> fact 6 + fact 7 5760 Fact> fact 7 `div` fact 6 7 Fact>
As another example, the standard formula for the number of different
ways of choosing r objects from a collection of
n objects is n!/(r!(n-r)!). A simple and
direct (but otherwise not particularly good) definition for this
function in Hugs can be added to fact.hs. Open the editor
by typing :e and then type:
comb :: Integer -> Integer -> Integer comb n r = fact n `div` (fact r * fact (n - r))
Notice the way you specify two parameters.
Another way to use this function is to include its definition as part of an expression entered at the Hugs prompt:
Fact> combin 5 2 where combin n r = fact n `div` (fact r * fact (n-r)) 10 Fact>
The definition of combin is local to this expression.
If we want to use the function several times, then it must be added to
the file Fact.hs. You can edit the last file you loaded by
typing :edit. This brings up a window for you to edit the
file. The interpreter is suspended until you save the file and exit
the editor. You can reload the previously loaded file by typing
:reload or simply :r. Once this has been done,
then we can use the comb function like any other built-in
operator:
Fact> :reload Fact> comb 5 2 10 Fact>
Names in Haskell
Identifiers must begin with a letter (small or capital) and be followed by an optional sequence of letters, digits, underscores and single quotes. Variables must be lower case. Capital letters are used to begin type names (such as Int), constructors (such as True or False), module names and the name of type classes.
Exercise 1: Create a function increment
which takes one argument and adds 1 to it.
Exercise 2: Create a function area
which takes two arguments representing length and width of a rectangle
and returns the area.
Last modified: Thu Nov 2 16:02:35 MST 2006 by Jerry James