Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Working in the GHC Interactive Environment
Index -> General Programming
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
wtd




PostPosted: Thu Mar 24, 2005 8:20 pm   Post subject: Working in the GHC Interactive Environment

One of the keys to learning any programming language is learning how to run programs. Most of the time, though, we simply create a program, possibly compile it, then run it. It either runs fine or quits with errors, or gives us output we didn't expect. We can then go back and make modifications to our program and start the whole process over again.

Some languages*, though, have an additional tool. An interactive interpreter, which lets us get inside the program and test each little piece of it separately.

Haskell is just such a language, having both the Hugs interpreter and the interpreter component of the Glasgow Haskell Interpreter. Hugs is a worthy program, but GHCI is the more updated program, so I'll be covering it here. Fortunately Hugs and GHCI function very similarly.

* Such languages include Ruby, Python, Objective-Caml, SML/NJ, and Scheme, among others.

First Steps

The first step in using GHCI, of course, is to install GHC itself. Linux users will likely be able to find a package for it using the package management tool of their choosing. For Windows users an installer is available (Windows users may need to reboot after installing).

Running GHCI is a simple matter of typing "ghci" at the command-line. The first thing you'll see is something like:

code:
$ ghci
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.2.2, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude>


The first bit is rather unimportant. Some nice ASCII art and a bit of info about the version of GHC Interactive, as well as information about how to get help.

The "Loading package base ... linking ... done" line gives us a bit of a hint as to what the compiler is doing in the background to prepare the environment.

The last line is the important one. The ">" is the prompt, at which we can enter expressions for GHCI to evaluate. Everything in front of it, in this case "Prelude" describes the modules which are currently loaded. The Prelude module is described here. In short it contains many useful functions, and it can be considered to be always available.

One use of this basic environment might be as an advanced calculator. The Prelude module includes a number of mathematical functions for just such a use.

code:
Prelude> sin (pi / 2)
1.0
Prelude>


Of course, there are times when we need functions not included in Prelude. Let's say we want to convert a String to all lowercase. Well, we need the "toLower" function which converts a character to lowercase. So we'd write it as:

code:
Prelude> map toLower "Hello"

<interactive>:1: Variable not in scope: `toLower'
Prelude>


What this is telling us is that the module toLower is in hasn't yet been imported. We can fix this by loading the Char module.

code:
Prelude> :m Char
Prelude Char> map toLower "Hello"
"hello"
Prelude Char>


Note that the prompt has changed to indicate that the Char module and all of its functions are also now fair game, in addition to those in Prelude.

Our own modules

Now, we can of course create our own modules and load them. Let's create a simple module in a file named SimpleModule.hs and give it a pretty simple function:

code:
module SimpleModule where

isDivisibleByThree number =
  mod number 3 == 0


Loading it into the interpreter is done like so:

code:
Prelude> :l SimpleModule

Compiling SimpleModule ( SimpleModule.hs, interpreted )
Ok, modules loaded: SimpleModule.
*SimpleModule>[/code]

Please note that if your code will not compile, it won't load here either.

Now, if we wish to run the function in our module:

code:
*SimpleModule> isDivisibleByThree 4
False
*SimpleModule> isDivisibleByThree 111
True
*SimpleModule>


Now, let's say we have the following module Main which contains the function main that just prints back all of the arguments fed into it which begin with 'h', and the helper function printOrNot which determines if a function should be printed:

code:
module Main where

import System
import List

main = do
  args <- getArgs
  mapM_ printOrNot args

printOrNot item =
  if isPrefixOf "h" item
    then putStrLn item
    else return ()


We can load it and run the main function like so:

code:
Prelude> :l Main
Compiling Main             ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
*Main>


So, why did nothing happen? Well, the getArgs function only gets the arguments that have been provided. Since we're not running this as a full-fledged program, there are no args. Fortunately, GHCI gives us a way to fake it for testing purposes.

code:
Prelude> :l Main
Compiling Main             ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main> :set args hello world foo bar
*Main> main
hello
world
foo
bar
*Main>


Finding Expression Types

Haskell is a very statically-typed language. Every function has very strict rules on what it will take and what it will return. As a result, we occassionally need to know what those types are.

Let's consider the 'map toLower "hello"' example used earlier. In it, "map toLower" is a function itself. Now, if we want to figure out what we can pass as an argument to this function we'll need to see its type. This is very easily accomplished.

code:
Prelude Char> :t map toLower
map toLower :: [Char] -> [Char]
Prelude Char>


Here we can see that it takes a list of characters ([Char]) and returns a list of characters. A list of characters is another way of saying "string." This same bit of syntax can be used with any expression or function.

Wrapping it up

I hope this has served to explain some of the most useful workings of the Haskell interactive environment, and made the language seem a little more accessible than it did before. Questions are, as always, welcome.
Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> General Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 1 Posts ]
Jump to:   


Style:  
Search: