Friday 29 April 2016

Introduction to Haskell

Welcome to the world of Haskell. Before going deep into the language let me explain what is Haskell, What are the key features of functional programming languages. Haskell is a pure functional programming language developed in late 1980s, it is named after Haskell Curry, was an American mathematician and logician. It incorporated many recent innovations in programming language design. It provides a  framework of elegant libraries to build complex and maintainable systems. First let me try to explain, what is functional programming. Following are the core concepts of functional programming.

a. Functions are the first class citizens in functional programming
Functions are the basic building blocks in functional programming, unlike object oriented programming languages; a function is not enclosed inside a class. A function can be passed as an argument to other function, a function can return result as a function, You can assign a function to a variable etc., In summary, you can use a function like variable.


For Example,
let sum x y = (x + y)


Above statement define a function named sum, which takes two number arguments and return the sum of two numbers. In Haskell, let key word is used to define variables, functions in Haskell interpreter.
Prelude> let sum x y = (x + y)
Prelude> 
Prelude> sum 10 20
30
Prelude> 
Prelude> let name = "Krishna"
Prelude> name
"Krishna"
Prelude>

You can learn Haskell basics without installing. Haskell home page
https://www.haskell.org/ provides user interface to communicate with Haskell interpreter.

b. Pure functional programming is side affect free
A Pure functional programming language has no side affects. A function is said to have side affect, if the result is not completely depend on its arguments. For example, a particular function might modify a global variable or static variable, modify one of its arguments, raise an exception, write data to a display or file, read data, or call other side-effecting functions. In the presence of side effects, a program's behavior may depend on history.


For example, observe following code.
public class ProcessData {
 private static int x = 10;

 public static int f(int a) {
  x = x + a;
  return x;
 }

 public static int g(int a) {
  x = x * a;
  return x;
 }
}


Result of functions f, g is depend on the global variable x, and result is also depend on the order of execution of functions f, g.

If you call function f(5) first followed by g(5), then f(5) return 15, g(5) return 75. If you call function g(5) first followed by f(5), then f(5) return 55, g(5) return 50.

A side affect free function always returns same value for same input, i.e., it doesn’t depend on any global variable, external data, and order of executions.

Note
Side affects (Such as writing data to external systems, read data from netwroks etc.,) are still possible in Haskell, but Haskell is designed like that, it separates the pure code from impure(side-affect) code.

c. Functions can take other functions as input and return a function as output
In functional programming a function can take other functions as input.

Prelude> let inc x = (x+1)
Prelude> let addBy1 fun x = fun x
Prelude> 
Prelude> addBy1 inc 10
11
Prelude> addBy1 inc 12
13

A function can return other function as output.    
Prelude> let mul x y = x * y
Prelude> let mulBy10 y = mul 10 y 
Prelude> 
Prelude> mulBy10 10
100
Prelude> mulBy10 11
110
Prelude> mulBy10 12
120


d. Function composition is every where
A function output can be passed as input to other function. Combining functions by passing output of one function as input to other function is called composition of functions.

For example,
Let g(x) = 2x, f(x) = x + 1
then
f(g(x)) = f(2x) = 2x + 1
g(f(x)) = g(x+1) = 2 (x+1) = 2x + 2

Prelude> let g x = 2 * x
Prelude> let f x = x + 1
Prelude> 
Prelude> f(g 10)
21
Prelude> g(f 10)
22


e. Functional programming support pattern matching
Patterns are very useful, to write clear and precise applications. In pattern matching, we attempt to match values against patterns, bind variables to successful matches.

You can perform pattern matching on any kind of data like tuples, lists, numbers, String etc., I will discuss about this in later sections.

f. Functional programming is lazy
In functional programming, expressions are not evaluated until their results are actually needed.

Prelude> take 50 [1..]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50]


[1..] represent infinite list, take function takes a number ‘n’ and list as arguments and return first ‘n’ number of elements.

g. In functional programming, you no need to worry about low level details

For example, you want to twice all the elements in a list, you will write following logic.
for(int i=0; i < list.size(); i++){
         list.set(i, 2*list.get(i));
}

Observe above snippet, you need to track some low level details like index, incrementing index after every iteration, setting the value after doubling etc.,

In case of functional programming ‘map (2*) [1, 2, 3]’ will perform same calculation.

h. Functional programs are easy to write, debug, maintain and expressive.

Following snippet implements quick sort algorithm. By looking into the code, you can easily guess what is happening here.
qsort [] = []
qsort (x:xs) = (qsort left) ++ [x] ++ (qsort right)
               where
                   left = filter (<= x) xs
                   right = filter (> x) xs


Don’t worry, if you don’t understand above program. You will get to know soon.

Let me try to brief you.

qsort [] = []
Above statement tells that, if you apply qsort on empty list, it should return empty list. Empty list is specified by [].

qsort (x:xs) = (qsort left) ++ [x] ++ (qsort right)
Suppose if your list has [3, 5, 1, 19], it is not empty, so it is mathced to the pattern (x:xs). If you apply pattern like this x is matched to 3 and xs matched to [5, 1, 19].

If (x:xs) is matched to list [3, 5, 1, 19], then x is 3 and y is [5, 1, 19]
If (x:y:xs) is matched to list [3, 5, 1, 19], then x is 3, y is 5 and xs is [1, 19]

left = filter (<= x) xs
Above statement tells, filter all the elements from list xs, such that all the elements in result list should be <= x.

right = filter (> x) xs
Above statement tells, filter all the elements from list xs, such that all the elements in result list should be > x.

i. Once you assign a value to variable, it never change. That means all the variables in functional programming are immutable.

j. Almost all functional programming languages provides automatic memory mamangement (Grabage Collection)

Note
a. Haskell is a lazy language that does calculations only when they are needed to get a final result.

b. Haskell is statically typed
Haskell types are checked at compile time. Once the Haskell program compiled, no more type checks happen at run time, it boost the performance a lot.

c. In one line, Haskell is polymorphically statically typed, lazy, purely functional language.

d. If you want to compare Haskell with other functional programming lanaguages,following link helps.

e. If you want to try simple Haskell commands in browser, following link helps

  
References






Previous                                                 Next                                                 Home

No comments:

Post a Comment