NOTIFICATION: These examples are provided for educational purposes. The use of this code and/or information is under your own responsibility and risk. The information and/or code is given ‘as is’. I do not take responsibilities of how they are used. You are welcome to point out any mistakes in my posting and/or leave a comment.
You are required to install Hugs in your system. I believe you can download it at this address: <http://hackage.haskell.org/platform/>. The Haskell platform is available form Windows® , Mac®, and Linux. For Debian distribution and derivation distributions such as Ubuntu, you can execute the following command line:
sudo apt-get install hugs
For editors, you can search on Internet. I personally use gedit.
A Little About Haskell
Haskell is a purely functional programming language which means that inputs will be applied on a mathematical function that will produce an output. There are no internal state; therefore, there is no possible side effects of the output. Also, Haskell is a strongly typed language.
At different of some imperative languages, Haskell provide:
- First-class function values: Normally, they can be passed as a parameter, assigned into a variable, and/or returned from a subroutine
- Higher-order functions: They are functions that can take a function as an argument, and/or return a function.
- Polymorphism / static polymorphism typing: Thorough mechanism of type inference, a function can be used on a general class of arguments.
- Monads: They allow the programmer to put together a sequence of actions that will be executed in a determined order. They are a solution to the problem of threading mutable state through a functional program.
- Monadic I/O, random numbers, mutable global variables, and shared-memory synchronization.
- Pattern matching
- Curried functions: A function with multiple arguments is replace with a function that takes a single argument and return a function with the remaining arguments.
- Non-strict semantics.
- Indentation-based (also known as layout) syntactic grouping.
- List type and list comprehension
- Operators.
- Structured function returns.
- Constructors (also known as aggregates) for structured objects.
- Garbage collection: The main purpose of garbage collection is to free memory after an object stop to be required so other program can use the free space.
Haskell apply lazy evaluation. This means that any evaluation will be evaluated if and only if the system required the evaluation to be evaluated. Also, it keep track of which evaluation have been already evaluated and keep the result in case it is needed more than once.
Typing Your First Message to The World and Play Around
Type Hugs on your command line and when you see Hugs> type putStr “Hello World!”
carlstein@your-computer:~$ hugs
__ __ __ __ ____ ___ _________________________________________
|| || || || || || ||__ Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__|| __|| Copyright (c) 1994-2005
||---|| ___|| World Wide Web: http://haskell.org/hugs
|| || Bugs: http://hackage.haskell.org/trac/hugs
|| || Version: September 2006 _________________________________________
Haskell 98 mode: Restart with command line option -98 to enable extensions
Type : ? for help
Hugs> putStr 'Hello World'
Hello World!
Hugs> putStr 'You can do Math too!'
You can do Math too!
Hugs> 4 * 4
16
Hugs> 4 `div` 2
2
Two different Style of Haskell
There are two ways to write a Haskell file;
- Traditional Haskell style:
- Files have the extension .hs
- Functions begin in the first column, any additional line of code must be indented.
- Any other new function definition must began after then end of previous (first function) function definition.
- One-line comments are prefixed with ‘- -‘
-- This is an example of one-line comment
- Multiple-lines comments are began with ‘{-‘ and ends with ‘-}’
{- This is an example
of multiple-lines comments -}
- Literal Haskell style:
- Files have the extension .lhs
- Every line is considered a comment.
This is a multiple line comment
This is another line of comment
- Code begin with ‘>’. Comments must be separated from the line of code by one space before and after the line of code.
This is a comment is before the code
> putStr 'Line one of code'
> putStr 'Line two of code'
This is a comment after the code
- A definition will end when the first piece of text (code or comments) lies at same indentation
- A definition will end when the first piece of text (code or comments) lies to the left of the start of the definition
- All definitions must begin at the same level of indentation
- Begin your files with defining them as a module
> module Example1
> where
Notice that a module begin with capital letter.
- To load your module type in hugs:
Hugs> :load YourModuleName
or
Hugs> :l YourModuleName
In either case, if there are not any errors the prompt of hugs should change to the name of your module:
YourModuleName>
We are going to focus these tutorial on Literal Haskell.
Libraries in Haskell
By default the programmer have the Prelude library at disposition. This is a default library that hold in-build functions. In order to include other libraries you can use import
> module Example1 where
> import List
Other libraries may be loaded together with the list library such as Prelude.hs, Maybe.hs, and List.hs.
A list of libraries available for the programmer can be fount at <http://www.haskell.org/ghc/docs/latest/html/libraries/>.
Defining Constants
> module Example1
> where
This define a constant
> valuePi :: Double
> valuePi = 3.14159
If we wish to know the type of valuePi we could use the following command ‘:t’
Hugs> :l Example1
Example1> :t valuePi
valuePi :: Double
Some basic type are: Int, Bool, Char, Float, Double, Integer, …
String is a list of characters. Prelude defines string
type String = [Char]
In Haskell, type is the equivalent of typedef in C
Function Definitions
There are two way to define a function:
- Implicity:
> module Example2a where
> cubeValue x = x * x^2
- Explicity:
> module Example2b where
> cubeValue2 :: Int -> Int
> cubeValue2 y = y * y^2
In both cases (implicit and explicit), “=” means ‘defined as‘ and “::” means ‘has type‘
Factorial Examples:
In the following example, we are showing: if/then/else statements, how indentation is performed, and how guards are used.
>module Example3 where
> factorial :: Int -> Int
> factorial x = if (x < 0) then error 'y can't be negative' else if (x==0) then 1 else x * factorial(x-1)
> factorial2 :: Int -> Int
> factorial2 y
> | y < 0 = error 'y can't be negative'
> | y == 0 = 1
> | otherwise = y * factorial(y - 1)
Regular Fibonacci Examples:
> module Example4 where
> fibonacci n
> | n == 0 = 1
> | n == 1 = 1
> | otherwise = fibonacci (n - 1) + fibonacci (n - 2)
Another way to write it
> fibonacci2 0 = 1
> fibonacci2 1 = 1
> fibonacci2 n = fibonacci2 (n - 1) + fibonacci2 (n - 2)
Using where clause
> fibonacci3 0 = 1
> fibonacci3 1 = 1
> fibonacci3 n = fibMinusOne n + fibMinusTwo n
> where
> fibMinusOne n = fibonacci3 (n - 1)
> fibMinusTwo n = fibonacci3 (n - 2)
If you wish you can check the type of these functions:
Example1> :l Example4
Example4> :t fibonacci
fibonacci :: (Num a, Num b) => a -> b
Example4> :t fibonacci2
fibonacci2 :: (Num a, Num b) => b -> a
Example> :t fibonacci3
fibonacci3 :: (Num a, Num b) => b -> a
Tuples
For those who are C programmers, I would say that tuples are non-homogeneous linear structures
such as structures in C. In C, we could have the following structure:
struct Person{
char * fullName;
int age;
} employee;
employee.fullname = &mathias_name; // Assuming mathias_name hold to a string 'mathias'
employee.age = 25;
In Haskell, we obtain the same in the following fashion:
> module Example5 where
> type Person = (String, Int)
> employee :: Person
> employee = ('Mathias', 25)
notice that Person goes with the first letter in capital since it is not a variable.
If we wish to obtain the name and age of the employee we can use fst and snd
Hugs> :l Example5
Example5> fst employee
'Mathias'
Example5> snd employee
25
fst is a function that return the first element of the tuple, while snd is another function that returns the second element of the tuple.
fst (x,y) = x
snd (x,y) = y