CS 214: Programming Languages
Spring 2009

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

Composing Functions
Haskell, Iteration 6

In this iteration, you will be using Haskell's composition operator to compose new functions from old ones.

Set Up

Create a _languages/haskell/iteration06 folder. Create a module Composition in a file Composition.hs; write a corresponding CompositionTest.hs test file.

Yet Another Way to Define a Function

You've seen several ways to create functions:

Define functions double and square in the Composition module to double a number and to multiply a number by itself, respectively. Test them in CompositionTest.

That gives you something to start with. Consider these two functions:

double_square = (double . square)
square_double = (square . double)

What do you suppose these do?

Define these functions in Composition.

You'll need to load the Composition module into GHCi.

Prelude> :load Composition

The GHCi prompt should change.

Try out these two new functions in GHCi using floating point numbers. Define some tests in CompositionTest, compile, and green bar.

If you ever change Composition, you'll need to relaod the module:

Prelude Composition> :reload

A very serious question to consider: how appropriate are the names? Do the words seem like they're in the right order? (Hint: I don't know!)

You can also compose curried functions.

list_double_and_square1= (map double) . (map square)

Try this out in GHCi. Test it. Green bar.

Write a list_double_and_square2 which yields the same results as list_double_and_square1 but uses only one map. Test, and green bar.

Here are more functions to define with composition and to test:

  1. sum_of_squares which squares every elements of a list and sums them up.
  2. sum_of_evens which sums up the even numbers in a list.
  3. sum_of_squares_of_positives which should add up the sum of squares of positive numbers found in a list.
  4. exponents should compute an exponential expression from a list. That is, exponents [2, 3, 4] will compute 234. Hint: Haskell has an exponential operator **. Another hint: exponentiation is right commutative.
  5. Start with this function:
    goofy1 = (map (+1)) . (filter (>1))
    
    Test it. Then write a goofy2 which flips the order of map and select and still computes the same result. Hint: when mapped over the list [0, 1, -1, 2, -2, 3, -3], you may get differing results.
  6. Haskell already has a reverse function. Write your own myReverse which uses a fold function.

Hint, to build lists: 1 : 2 : 3 : [] is [1, 2, 3]. Also, [1] ++ [2] ++ [3]

Questions to consider for an exam: