CS 214: Programming Languages
Spring 2009

Home|Syllabus|Schedule
<<|>>|Haskell templates

The "Hello, World!" Functional Program
Haskell, Iteration 1

There are three aspects of Haskell that make it particularly interesting:

However, we won't look at any of these things this week. This week is to get a Haskell environment working for you.

Not Really Printing "Hello, World"

Your first Haskell program is going to be a program that computes factorials.

In your cs214/haskell folder, create a folder named factorial. In this folder, create these files: Factorial.hs, FactorialTest.hs, FactorialMain.hs, and Rakefile.

Unit Tests

Let's start with the unit tests.

FactorialTest.hs

module Main where

import Test.HUnit
import System
import Factorial

{- This is a TestList of TestCases.  Each TestCase should make one
   assertion.  You can define as many of these variables as you like. -}
factorialTests = TestList [
  TestCase (assertEqual "0! should be 1" 1 (factorial 0)),
  TestCase (assertEqual "1! should be 1" 1 (factorial 1)),
  TestCase (assertEqual "3! should be 6" 6 (factorial 3))
  ]

{- Just accept this next bit of code -}
checkTests counts = case counts of
        Counts _ _ errors failures ->
                if (errors + failures > 0)
                then exitFailure
                else (exitWith ExitSuccess)

{- This is the main function which will be executed when the executable
   is invoked on the command line. -}
main = runTestTT
        (TestList [
          TestLabel "testing factorial" factorialTests
          {- If you define more test variables, add TestLabels here -}
          ])
       >>= checkTests

Put this code into FactorialTest.hs.

Computation

Factorial.hs

module Factorial where

factorial 0 = 1
factorial n = n * factorial(n-1)

Put this code in Factorial.hs.

Managing the Compilation

A rakefile is actually a Ruby program using the rake gem. It can be used to compile any language though:

Rakefile

task :default => :compile

task :compile do
  system "ghc --make FactorialTest.hs"
end

Enter this code into Rakefile.

Running the Tests

You can now compile and run the tests!

Compile everything with the rake command. Then run FactorialTest.

Add to the Tests

Add some more TestCases to FactorialTest.hs. Test 6!, 13!, and 100!.

A couple things to observe:

Try Interactive Haskell

Start ghci at a command line in your factorial folder. Enter these commands:

> :load Factorial
> factorial 100

Compute some other factorials.

Main Function

FactorialMain.hs

module Main where

import Data.String
import System.Environment
import System.Exit

import Factorial

{- main program function.  Applies "factorial" to all arguments. -}
main = getArgs >>= putAnswers . (map factorial) . parse

{- gets the command-line arguments -}
parse args     = map read args

{- print results -}
putAnswers l   = putStr (unlines (map show l))

Be sure to mention to your other computer-science profs how fast Haskell can compute very large factorials.

Put this code into FactorialMain.hs. Add code to Rakefile to compile this program as well. Then run FactorialMain like so:

% FactorialMain 100