Skip to 0 minutes and 4 secondsJEREMY: Hi. Now, you have installed the Haskell platform, let's start using it. I'm in a terminal window here on my Mac OS laptop. You could do something similar on your Linux machine or maybe a DOS prompt in Windows. And I'm going to type in 'ghci', which is the interpreter for the Glasgow Haskell compiler. Press Enter. And look, it loads up. I'm running version 7.10 here. You might have a slightly different version, but hopefully, everything should work out fine. Notice that the prompt here, the interactive prompt, it says Prelude, which indicates that the standard Haskell library, Prelude, has been loaded. First of all, I'm going to type in a string-- "hi everyone." And this string value is returned for me.
Skip to 0 minutes and 56 secondsI can see the type of 'hi everyone."
Skip to 1 minute and 0 secondsIf I go to the start of the line and say ':type' --
Skip to 1 minute and 8 secondsthis is a GHCi command here-- ':type' "hi everyone" tells me that "hi everyone" is of type character list, which is equivalent to String, as you know. I can type in numbers, as well. Here's 42. Arithmetic expression-- here's 1 plus 1. I can also use variables like x equals 3. And from now on, I can use x or use x inside arithmetic. Good. I could also call functions on strings. So let's find out the length of "hi everyone." We can also reverse "hi everyone," which shows that that "enoyreve ih" is "hi everyone" written backwards. These standard functions, length and reverse, are defined for us in the Haskell Prelude.
Skip to 2 minutes and 6 secondsNow, we're going to define a function. Just inside the GHCi interactive prompt we can define the factorial function. Let fact n equal-- remember this is the product of the first n positive numbers. If n==0, then fact of 0 is 1 else. We want to compute n times fact n minus 1. So if I say fact of 0, that should give us back 1. That's the then case. If I say fact of 3, that gives us 3 times 2 times 1, which is 6. Fact of 5 is 120 and so on. So you see that we can define functions using let and then give the single line function definition here inside GHCi.
Skip to 2 minutes and 58 secondsIt might be the case that we actually want to define a function in a Haskell source code file. So let's do that now. I'm going to start up the gedit text editor, and I'm going to create a new file. I'm going to save this file in the folder I'm in, which is-- let's find it quickly. I'm in the right folder now. And I'm going to call this file factorial.hs Haskell source code. So simple factorial definition-- so I can say fact2-- let's give this a different name to the previous one-- takes an integer and returns an integer. That's the signature for the function.
Skip to 3 minutes and 56 secondsFact2 n equals-- and I can use the same definition of n==0 then 1 else n times fact2 of n minus 1. Great. So let's save this file-- save. And then, we'll go back to GHCi.
Skip to 4 minutes and 21 secondsThere we go-- GHCi, :load factorial.hs.
Skip to 4 minutes and 29 secondsAnd it loads. So you can use relative pathnames-- relative to the directory that GHCi is running in-- or you can use an absolute pathname, as well, if you have the full name of the directory where the file is stored. I've loaded the factorial file now. And it's loaded OK without any problems. So now, I can say fact2 of 10, while it calculates the factorial. I can work up the type for fact2. It takes an integer argument and returns integer results.
Skip to 5 minutes and 2 secondsNotice the ':t' is shorthand for the type command. There we go-- same again. And I could map fact2 over 1 to 10. And there we go. Now, let's go and have another look at the definition of fact2.
Skip to 5 minutes and 24 secondsWe could actually rewrite this definition to make it a little bit neater.
Skip to 5 minutes and 37 secondsLet's try and save this and then :reload fact2-- load factorial-- it's loaded again. And now, we can rerun the same command and get the same results. And perhaps, the function looks a bit more elegant now. What happens if I say fact2 of minus 1? Oh, sorry. I need to put minus 1 inside brackets. Otherwise, it's trying to subtract 1 from the fact2 function. Let's try this again. It starts running, and It runs and carries on running for a long time. This doesn't match the first case because the input isn't 0. So it matches the second case, which multiplies the number by one less than the number.
Skip to 6 minutes and 25 secondsSo we get minus 1 times minus 2 times minus 3 times minus 4, ad infinitum. We may get a stack overflow eventually, but I can't afford to wait that long. So I'm going to press Control-C and then Enter. And hopefully, this should stop the computation.
Skip to 6 minutes and 46 secondsTo quit GHCi, I type in ':quit', and I drop back into my command prompt. Let's start again. I could also quit by typing Control-D. That gets me out, as well.
Skip to 7 minutes and 2 secondsLet's do some IO-- putStrLn "hello." It might be the case that I want to read in some input from the keyboard and then print out to the output. So I'm going to say, do. And x is getLine. Look, I get error message here, which says "The last statement in 'do' block must be an expression." What I wanted to do there was write myself a multi-line do statement. But actually, I wasn't able to do that. I need to say, set +m, in the GHCi environment to allow multi-line statements. Now, I can say, do x is getLine, line up the do commands. And now, I'm going to say, putStrLn "hello," concatenated with x. Right.
Skip to 8 minutes and 8 secondsI pressed Enter twice, and that got me out of the do construct. And now, GHCi is waiting for my input. So I'm just going to type in my name, Jeremy, Enter, and back comes "hello Jeremy." So the do has been evaluated.
Skip to 8 minutes and 29 secondsLet's write ourselves one more function. I'm going to go back to get it. And I'm going to write myself a new function, which I'm going to call nobles.hs.
Skip to 8 minutes and 49 secondsMake people noble-- so mknoble is going to take a string parameter and return a string result. And I'm going to say mknoble. If I receive a name, then I'm going to return "Sir" plus that name ++ for concatenation. OK, let's save this. And now, we should be able to load it into GHCi-- load nobles. And now, I can say, mknoble "Alex Ferguson," and "Sir Alex Ferguson" returns. That's great-- just go back here. I wonder what happens if I want to make a female person noble. Well, I really need another argument here, Boolean, that allows me to say, if-- well, let's give this parameter a name, female.
Skip to 9 minutes and 52 secondsIf female-- sorry-- then "Dame" else "Sir" ++ name. That's all on one line. It just looks a bit messy. Perhaps I should move this along a bit so it's on the next line. I need to indent it more than the if statement. OK, so now, I'm going to save that file and go and load it again. Colon l is short for load-- nobles.hs. Now, I can mknoble. If I try and mknoble "Alex Ferguson," it's going to complain because I haven't said whether he's male or female. So look, it says now, "Couldn't match expected type of 'Bool' with the actual type 'Char'" because the first parameter should be a Boolean where I would have given it a string.
Skip to 10 minutes and 47 secondsSo we need to say mknoble False because "Alex Ferguson" is not a female. And now, it says, "Sir Alex Ferguson." And then, I say mknoble True "Helen Mirren." That becomes "Dame Helen Mirren." Great. So that's a function we defined here.
Skip to 11 minutes and 4 secondsWe can see the type of the function, :type mknoble, and now, it takes a Bool, then a string, and then returns a string. Great. Let's quit. And I hope you have fun playing with GHCi. And again, if you have any problems or questions, let us know in the comments section below. Thanks.
How to Run GHCi
We used the online Haskell interpreter (tryhaskell) for the first few programming exercises. Now we want to move to GHCi, for some larger and more complex Haskell development.
© University of Glasgow