So far, we have confined ourselves to the walled garden of CodeWorld. This provided us a smooth start, but of course Haskell is much more than that. This week we will learn about “real” Haskell: How to run it locally, how to compile programs, and what the standard libray provides for us.

# More ways to run Haskell

In order to use Haskell locally, we have to install it first. I will not go into the details of that now. Just follow the links on the resources page. There are plenty of competing installation instructions out there in the world. I do not particularly care which one you follow, but make sure you get GHC-7.10.3.

Once installed, you have two new programs ghc and ghci. The former is the compiler:

$ghc ghc: no input files Usage: For basic information, try the `--help' option. Without an input file it does little. ## The interpreter The latter is an interpreter:$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude>

and running it gives us a prompt where we can now go ahead and evalute Haskell expressions:

Prelude> 1+1
2
Prelude> 2^2^2
16
Prelude> 2^2^2^2
65536
Prelude> 2^2^2^2^2
2003529930406846464979072351560255…

Besides evaluating expressions, we can bind variables or define functions (using let), and even declare data types:

Prelude> data Pair a = Pair a a deriving Show
Prelude> let four x = Pair (Pair x x) (Pair x x)
Prelude> let fourTrues = four True
Prelude> fourTrues
Pair (Pair True True) (Pair True True)

There are a few useful command that allow us to query the interpreter:

Prelude> :t four
four :: a -> Pair (Pair a)
Prelude> :i Pair
data Pair a = Pair a a           -- Defined at <interactive>:15:1
instance Show a => Show (Pair a) -- Defined at <interactive>:15:31

It is also possible to enter mult-line functions definition into the interpreter, but that gets quickly unweildy. But there is a better way: You can load files into the interpreter.

So here I load last week’s homework. The file gets loaded as Main, and I can use the :browse command to see the contents of the file:

$ghci LastWeek.hs GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Main ( LastWeek.hs, interpreted ) Ok, modules loaded: Main. *Main> :browse Main main :: IO () data List a = Empty | Entry a (List a) mapList :: (a -> b) -> List a -> List b combine :: List Picture -> Picture allList :: List Bool -> Bool So we can play around in the file: *Main> let list = Entry 23 (Entry 42 Empty) *Main> nth list 2 42 *Main> mapList (+1) list <interactive>:7:1: No instance for (Show (List b0)) arising from a use of ‘print’ In the first argument of ‘print’, namely ‘it’ In a stmt of an interactive GHCi command: print it The latter did not work. We can deduce from the error message that the interpreter is using the command print to print out the results, and that this function requires its argument to be of a type that has a Show instance. Luckily, that instance can also be dervied. So after editing the file, adding deriving Show to the data List a = … line, I can reload the file with :r and now this works (but I have to redefine list – all definitions are lost when you reload): *Main> :r [1 of 1] Compiling Main ( LastWeek.hs, interpreted ) Ok, modules loaded: Main. *Main> let list = Entry 23 (Entry 42 Empty) *Main> mapList (+1) list Entry 24 (Entry 43 Empty) I can also, if I so want, run the main function from the interpreter: *Main> main Open me on http://127.0.0.1:3000/ In this case, because main calls interactionOf, this starts a local webserver that I can access in the browser and play our game. It keeps running even when I close the tab; I have to press Ctrl-C to return to the prompt of the interpreter. ## Compiling a program But clearly, entering main in the interpreter is not the desired way of running a program. Therefore, we use the compiler to produce a binary that we can run like any other compiled program of any other programming language:$ ghc -O LastWeek.hs
[1 of 1] Compiling Main             ( LastWeek.hs, LastWeek.o )
$./LastWeek Open me on http://127.0.0.1:3000/ Application needs to be re-compiled with -threaded flag ExitFailure 1 Nice, the program runs, but complains about a missing compile-time flag. So let’s just do what it says – for your own non-codeworld programs, this is not necessary:$ ghc --make -O -threaded LastWeek.hs