# The Easy Part

## Hello, World!

The first step in learning any programming language is the 'hello, world' program. Here's the Haskell version.

 hello.hs 1 main = putStrLn("Hello, world!") ```\$ ghc --make hello.hs [1 of 1] Compiling Main             ( hello.hs, hello.o ) Linking hello ... ``` ```\$ ./hello Hello, world! ```

In Haskell, as in C, you have to define "main" in order to create an executable. Haskell, however, does not use the curly braces.

## Numbers

 math1.hs 1 main = putStrLn(show(3+4*9)) ```\$ ghc --make math1.hs [1 of 1] Compiling Main             ( math1.hs, math1.o ) Linking math1 ... ``` ```\$ ./math1 39 ```

To obtain numeric output, it is necessary for us to convert the result to a string in order to print it. We do that with show().

## String Concatenation

 math2.hs 1 main = putStrLn("3+4*9="++show(3+4*9)) ```\$ ghc --make math2.hs [1 of 1] Compiling Main             ( math2.hs, math2.o ) Linking math2 ... ``` ```\$ ./math2 3+4*9=39 ```

String concatenation is accomplished with the ++ operator.

## Let Blocks

 math3.hs 1 main = 2 let 3 x = y+2 4 y = 3 5 z = y+1 6 in 7 putStrLn("x="++show(x)++", z="++show(z)) ```\$ ghc --make math3.hs [1 of 1] Compiling Main             ( math3.hs, math3.o ) Linking math3 ... ``` ```\$ ./math3 x=5, z=4 ```

In order to set variables you need to use a "let" block. You'll notice that both x and z depend on y, but y is defined after x and before z. This is possible because Haskell is a functional language. That means that variables are defined when they are set, and never change in value. That means that order of assignment is not important.

The other thing to notice is that blocks are defined by whitespace, just as they are in python. If you prefer to use curly braces, like C or java, this is possible.

## Defining functions

 fib.hs 1 fib n = 2 if n < 2 then 3 1 4 else 5 fib (n-1) + fib (n-2) 6 7 main = putStrLn(show(fib 10)) ```\$ ghc --make fib.hs [1 of 1] Compiling Main             ( fib.hs, fib.o ) Linking fib ... ``` ```\$ ./fib 89 ```

Here we see our first example of a function that takes an argument. In this case, it is the inefficient implementation of the Fibonacci function.

One important thing to note here is that function names are never capitalized. Capitalized identifiers must refer to type names in Haskell.

 fib2.hs 1 fib 0 = 1 2 fib 1 = 1 3 fib n = fib (n-1) + fib (n-2) 4 5 main = putStrLn(show(fib 10)) ```\$ ghc --make fib2.hs [1 of 1] Compiling Main             ( fib2.hs, fib2.o ) Linking fib2 ... ``` ```\$ ./fib2 89 ```

Here we see a slightly prettier version of the Fibonacci using what are called "patterns" to handle the condition where n < 2.

 fib3.hs 1 fib n 2 | n==0 = 1 3 | n==1 = 1 4 | otherwise = fib (n-1) + fib (n-2) 5 6 main = putStrLn(show(fib 10)) ```\$ ghc --make fib3.hs [1 of 1] Compiling Main             ( fib3.hs, fib3.o ) Linking fib3 ... ``` ```\$ ./fib3 89 ```

Another variant, called "guards" can be used to do the same thing.

One of the characteristics of the function defined above is that it is referentially transparent. This means that if a function is called twice with the same arguments, the compiler is free to replace the second function call with the value obtained by the first.

Furthermore, there is no way to determine what order fib(n-1) and fib(n-2) will evaluate. The compiler is free to attempt either computation first.

## Lazy Evaluation

 fib4.hs 1 fib 0 = 1 2 fib 1 = 1 3 fib n = fib (n-1) + fib (n-2) 4 5 main = 6 let 7 f1000 = fib 1000 8 hi = putStrLn("hello") 9 in 10 putStrLn(show(fib 10)) ```\$ ghc --make fib4.hs [1 of 1] Compiling Main             ( fib4.hs, fib4.o ) Linking fib4 ... ``` ```\$ ./fib4 89 ```

Haskell is lazy. That means, it doesn't compute a value if it does not have to. In this case, neither the variables f1000 nor hi are computed. Fib3 evaluates as quickly as fib2, and does not print the word "hello."

## More than one line of output

 several.hs 1 main = 2 do 3 putStr("Line 1: ") 4 putStrLn("one line of output") 5 putStr("Line 2: "); 6 putStrLn("another line of output") 7 putStr("Line 3: "); 8 putStrLn("another line of output") ```\$ ghc --make several.hs [1 of 1] Compiling Main             ( several.hs, several.o ) Linking several ... ``` ```\$ ./several Line 1: one line of output Line 2: another line of output Line 3: another line of output ```

In order to do more than one line of output, you need to use a "do" block. It is a special construct for stitching together a number of output commands. Inside a do block, each command will execute independently and in order. This gets around all the limitations imposed by functional programming.

Note also the use of putStr() vs. putStrLn(). The putStr() function does not output a carriage return / line feed.

## Loops

 loop.hs 1 again nlo nhi = 2 if nlo == nhi then 3 putStrLn("n = "++show(nlo)) 4 else 5 do 6 putStrLn("n = "++show(nlo)) 7 again (nlo+1) nhi 8 main = again 1 10 ```\$ ghc --make loop.hs [1 of 1] Compiling Main             ( loop.hs, loop.o ) Linking loop ... ``` ```\$ ./loop n = 1 n = 2 n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 n = 9 n = 10 ```

Here we put all the information above together to teach you how to write a simple loop. Because the if statement was outside the do block we were forced to write the putStrLn("n="...) line twice.

 loop2.hs 1 again nlo nhi = 2 let 3 putn = putStrLn("n = "++show(nlo)) 4 in 5 if nlo == nhi then 6 putn 7 else 8 do 9 putn 10 again (nlo+1) nhi 11 main = again 1 10 ```\$ ghc --make loop2.hs [1 of 1] Compiling Main             ( loop2.hs, loop2.o ) Linking loop2 ... ``` ```\$ ./loop2 n = 1 n = 2 n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 n = 9 n = 10 ```

That's still not elegant. However, there is another option. Case statements are allowed inside do blocks:

 loop3.hs 1 again nlo nhi = 2 do 3 putStrLn("n = "++show(nlo)) 4 case (nhi-nlo) of 5 0 -> putStr "" 6 otherwise -> again (nlo+1) nhi 7 8 main = again 1 10 ```\$ ghc --make loop3.hs [1 of 1] Compiling Main             ( loop3.hs, loop3.o ) Linking loop3 ... ``` ```\$ ./loop3 n = 1 n = 2 n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 n = 9 n = 10 ```

The tricky thing about case statements is that their patterns must be compile time constants. You can't use "nhi ->" in your code. That's why we chose to switch on (nhi-nlo) rather than nlo.

Of course, we could have simply inverted the if and do blocks like so:

 loop4.hs 1 again nlo nhi = 2 do 3 putStrLn("n = "++show(nlo)) 4 if nlo == nhi 5 then putStr "" 6 else again (nlo+1) nhi 7 8 main = again 1 10 ```\$ ghc --make loop4.hs [1 of 1] Compiling Main             ( loop4.hs, loop4.o ) Linking loop4 ... ``` ```\$ ./loop4 n = 1 n = 2 n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 n = 9 n = 10 ```

## Recursion

If you are a C programmer, using recursion may worry you. The following C program would probably seg fault because it would completely exhaust the stack:

 inf.c 1 #include  2 3 void inf(int n) { 4 if(n == 0) { 5 printf("done\n"); 6 return; 7 } 8 inf(n-1); 9 } 10 11 int main() { 12 inf(10000000); 13 return 0; 14 }

The equivalent Haskell program, however, is smart enough not to grow the stack because it knows that it is not really necessary since the above code is logically equivalent to a loop.

 inf.hs 1 inf 0 = putStrLn("done") 2 inf n = inf (n - 1) 3 main = inf 10000000 ```\$ ghc --make inf.hs [1 of 1] Compiling Main             ( inf.hs, inf.o ) Linking inf ... ``` ```\$ ./inf done ```

## Changing State

If you still want think imperatively, you can just use a function call whenever you normally use a state change.

 statesc.c 1 #include  2 3 void foo(int a) { 4 printf("a=%d\n",a); 5 a ++; 6 printf("a=%d\n",a); 7 } 8 9 int main() { 10 foo(1); 11 return 0; 12 } ```\$ gcc -o statesc statesc.c ``` ```\$ ./statesc a=1 a=2 ```
 states.hs 1 foo2 a = 2 putStrLn("a="++show(a)) 3 4 foo a = 5 do 6 putStrLn ("a="++show(a)) 7 foo2 (a+1) 8 9 main = foo 1 ```\$ ghc --make states.hs [1 of 1] Compiling Main             ( states.hs, states.o ) Linking states ... ``` ```\$ ./states a=1 a=2 ```

These loop and state examples probably make you think that Haskell is a cumbersome difficult language -- but really, this is not illustrative of the Haskell way of doing things. It is more like the C way of doing things shoe-horned into Haskell.

But hey, we have to start somewhere.

 next