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 one at the top level—and this alone can be done multiple ways! (See your factorial functions.)
- Partially evaluate a function (e.g.,
(2/)
and(/2)
). - Use a lambda expression (e.g.,
\n -> n % 2 == 0
).
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:
sum_of_squares
which squares every elements of a list and sums them up.sum_of_evens
which sums up the even numbers in a list.sum_of_squares_of_positives
which should add up the sum of squares of positive numbers found in a list.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.- Start with this function:
goofy1 = (map (+1)) . (filter (>1))
Test it. Then write agoofy2
which flips the order ofmap
andselect
and still computes the same result. Hint: when mapped over the list[0, 1, -1, 2, -2, 3, -3]
, you may get differing results. - Haskell already has a
reverse
function. Write your ownmyReverse
which uses afold
function.
Hint, to build lists: 1 : 2 : 3 : []
is [1,
2, 3]
. Also, [1] ++ [2] ++ [3]
Questions to consider for an exam:
- Why the difference between
goofy1
andgoofy2
? - Which works better for
myReverse
:foldl
orfoldr
? - How are these two questions related?