Abstract :: We present a “Hello World” program for Haskell, followed by some technical facts about the Haskell language. Essentially, we briefly summarise some parts of the first chapter of Real World Haskell.
a first program
Make a file named
myprog.hs with contents
main = putStrLn "Hello World"
runghc myprog.hs in a command line to execute this program.
runghc is a program for running Haskell programs as scripts, without needing to compile them first. In contrast,
ghci is an interactive interpreter and debugger.
The rest of this page consists of tidbits on numbers, lists, operators and interactive debugging of Haskell programs.
the wonders of ghci
ghci is a Haskell interpreter and run from a console by running
ghci myprog.lhs. Entering
:? at the
ghci prompt yields a collection of helpful commands to run. For example,
:module + Data.Ratio loads the
Data.Ratio module into the current session.
:t identifierto obtain type information for
- At the ghci prompt, the variable
itrefers to the previously evaluated expression. This makes it easier to work with previous expressions.
:rto reload your file after you’ve made some changes
I personally use
ghci as an overglorified calculator XD
operators in Haskell
Operator symbols appear infix as in most other languages, eg
3 + 4, but can also appear in prefix form by parenthesising them:
(+) 3 4.
Haskell uses nearly the same names for the common arithmetical and logical operators with notable exceptions being
** for exponentiation,
/= for non-equality, and
not for Boolean negation. The
^ has an integer as the exponent but
** allows the exponent to be fractional.
ghci prompt, we can run
:info (op) to see the precedence level of
op, with 9 being the highest level and 1 the lowest. For example,
infixl 6 means that the operator has level 6 precedence and is by default
left-associative; the alternatives are
infixr, infix for infix with default
right-associative parsing, and for infix with no specified parsing order. The associativity determines whether an expression containing multiple uses of an operator is evaluated from left to right or right to left; eg how do you normally parse repeated fractions
:info (/) to find out what Haskell does! 😛
negation and parenthesisation
The usual notion of subtraction and negation is to use the same overloaded symbol
- and Haskell accepts this and so the former is a binary operation whereas the latter is unary. In particular, if we wish to negate a number enclosed in some expression
f, we must write
f (-3) rather than
f -3 since the latter is ambiguous and may be parsed as the subtraction of
Note that function calls in Haskell do not require superfluous enclosing parenthesis as in other languages, unless there would be ambiguity otherwise. Function application has the highest binding: It is done first.
Moreover, Haskell allows us to define our own operators! More on this later. Hence, spacing about operators is important! 😮
In doubt, parenthesis your expressions.
lists, the bread and butter of Haskell programmers
A list is surrounded by square brackets and its elements are separted by commas as in
[1,2,4,8,16,32,64] for the list of a few powers of 2. The empty list is denoted
If the elements belong to an enumerable type, such as the numbers or characters, then we can write
[x..y] to obtain the list starting at
x and enumerating upto
y. For numbers, we can specify the increment for each step by including the first two elements of the resulting list:
[x,y..z] produces the list
[x, x+d, x+2*d, ..., x+n*d] where d = y – x and x + n*d ≤ z. For example,
[1.0, 0.75..0] == [1.0, 0.75, 0.50, 0.25, 0]. Moreover,
[x..] produces the infinite list enumerated from
x onwards —infinite lists are very useful and implemented very simply and efficiently! Press
Ctrl C to stop a
ghci computation, such as that of evaluating
[1..]! Unless giving a step size, there are dangers with using enumerations with fractional endpoints.
Lists can be catenated together to form longer lists using
++ and we can construct a new list given an element
x and a list
xs by the operation
: as in
Strings —formed by enclosing text in double quotes— are synonyms for lists of characters —which are formed by enclosing a symbol by single quotes. Eg “Hello” == [‘H’, ‘e’, ‘l’, ‘l’, ‘o’]. As such usual list operations work on Strings.
be rational; we’re nearly done
A rational number is a number expressible as a fraction of two integer numbers; for example, a third is rational since it equals
1/3 whereas the square root of two is not rational and this drove a few fanatical mathematicians too keep it secret…
Anyhow, Haskell treats rational numbers exactly in this form and one can construct them via the operator
%: the fraction with integer numerator
n and integer denominator
d is named
n % d. This way we can do very “precise” arithmetic since we do not express the rationals in floating-point form. Eg which is better
1 % 3 or
0.333, no matter how many trailing 3’s the latter will always be worse than the former; incidentally, three times the former is 1 but three times the latter is close to 1, but is not 1!