A brief introduction to Haskell
Inspired by the Introduction to OCaml.
- A language developed by the programming languages research community.
- Is a lazy, purely functional language (that also has imperative
features such as side effects and mutable state, as well strict evaluation)
- One of the youngest children of ML and Lisp
- Particularly useful for manipulating data structures, (i.e. compilers and interpreters), and parallel programming
- 1990. Haskell 1.0
- 1991. Haskell 1.1
- 1993. Haskell 1.2
- 1996. Haskell 1.3
- 1997. Haskell 1.4
- 1998. Haskell 98
- ~2007. Haskell Prime
Has some novel features relative to Java (and C++).
- Immutable variables by default (mutable state programmed via monads)
- Pure by default (side effects are programmed via monads)
- Lazy evaluation: results are only computed if they're required (strictness optional)
- Everything is an expression
- Completely higher-order functions: functions can be defined anywhere in the code, passed as arguments, and returned as values.
- Both compiled and interpreted implementations available
- Full type inference -- type declarations optional
- Pattern matching on data structures -- data structures are first class!
- Parametric polymorphism
- Bounded polymorphism (based on type classes)
These are all conceptually more advanced ideas, for the average imperative language.
Compared to similar functional languages, GHC Haskell contains several newer language features:
- Type classes
- Generalised algebraic data types
- Impredicative type system
- Software transactional memory
- Parallel, SMP runtime system
Read the language definition section of the manual to supplement these notes. For more depth and examples see here[http://haskell.org/haskellwiki/Books_and_tutorials.
= Interacting with the language
Interacting with Haskell via the GHCi interpreter:
- expressions are entered at the prompt
- newline signals end of input
Here is a GHCi sessoin, starting from a UNIX prompt.
$ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.4.2, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help.
Loading package base-1.0 ... linking ... done.
Prelude> let x = 3 + 4
- Here the incredibly simple Haskell program
let x = 3+4is
compiled, loaded, and bound to the variable
Prelude> :t x x :: Integer
We can ask the system what type it automaticaly inferred for our
x :: Integer means that the variable
x "has type"
Integer, the type of unbounded
Prelude> x 7
A variable evaluates to its value.
Prelude> x + 4 11
x is in scope, so we can reuse it in later
Prelude> let x = 4 in x + 3 7
Local variables may be bound using
let, which declares a
new binding for a variable with local scope.
Alternatively, declarations typed in at the top level are like an open-ended let:
Prelude> let x = 4 Prelude> let y = x + 3 Prelude> x * x 16 Prelude> :t x x :: Integer Prelude> :t y y :: Integer Prelude> :t x * x x * x :: Integer
Notice that type inference infers the correct type for all the expressions, without us having to ever specify the type explicitly.
There is a range of basic types, defined in the language Prelude
Int -- bounded, word-sized integers Integer -- unbounded integers Double -- floating point values Char -- characters String -- strings () -- the unit type Bool -- booleans [a] -- lists (a,b) -- tuples / product types Either a b -- sum types Maybe a -- optional values
7 12312412412412321 3.1415 'x' "haskell" () True, False [1,2,3,4,5] ('x', 42) Left True, Right "string" Nothing, Just True
These types have all the usual operations on them, in the standard libraries.