Skip to content
UoL CS Notes

Lecture 24-1

COMP105 Lectures

Writing Programs

To write a program in Haskell we write a main function.

main :: IO ()
main = putStrLn "Hello world!"

main always:

  • Takes no arguments
  • Returns an IO type.

To run the program, we first need to compile it:

 $ ghc -dynamic hello.hs 
[1 of 1] Compiling Main ( hello.hs, hello.o )
Linking hello ...
 $ ./hello

As I am running arch Linux with dynamically linked libraries I must use the -dynamic flag when compiling. For distros with static libraries this is not required.

Command Line Arguments

Most command line programs take arguments:

  • getArgs :: IO [String] returns those arguments.
  • This function is in System.Environment
import System.Environment

main :: IO ()
main = do
    args <- getArgs
    let output = "Command line arguments: " ++ show args
    putStrLn output

This function will return the command line arguments as a list of strings.

Looping in IO Code

The only way to loop in IO code is to use recursion.

printN :: String -> Int -> IO ()

printN _ 0 = return ()
printN str n =
    do
        putStrLn str
        printN str (n-1)

This program will write back a given string n times to separate lines.

  • No variables.
  • No loops.

Using Command Line Arguments

import System.Environment
main :: IO ()
main = do
    args <- getArgs
    let n = read (args !! 0) :: Int
    printN (args !! 1) n
 $ ./repeat_string 3 hello
hello
hello
hello

File IO

readFile will read the contents of a file:

readFile :: String -> IO String

Suppost that example.txt contains:

line one
line two
line three
> readFile "example.txt"
"line one\nline two\nline three\n"

writeFile writes a string to a file.

writeFile :: String -> String IO ()

The file will be overwritten!

> writeFile "output.txt" "hello\nthere\n"

The file output.txt will then contain:

hello
there

Finishing the marks.csv Example

We wrote the report function in Lecture 18-1. Now we can turn it into a program:

import System.Environment
main :: IO ()
main = do
    args <- getArgs
    let infile = args !! 0
        outfile = args !! 1
    input <- readFile infile
    writeFile outfile (report input)

Exercises

  1.  import System.Environment
     main :: IO ()
     main = do
         args <- getArgs
         infile <- readFile (args !! 0)
         let string = (lines infile) !! 0
         putStrLn string
    
  2.  import System.Environment
     main :: IO ()
     main = do
         args <- getArgs
         let num = read (args !! 0) :: Int
         putStrLn $ show (num + 1)
    
  3.  main :: IO ()
     main = do
         putStrLn "Write a line of text to be written to output.txt."
         string <- getLine
         writeFile "output.txt" (string ++ ['\n'])
    

    Remember to end files with \n so that they are read properly.