Skip to content
UoL CS Notes

Lecture 17-2

COMP105 Lectures

More Higher Order Functions - Continued

takewhile

This function takes while a condition is true.

> takeWhile (<=5) [1..10]
> [1,2,3,4,5]

This is different to filter which only removes individual elements.

> takeWhile (\ x -> length x <= 2) ["ab","cd","efg"]
> ["ab", "cd"]

Implementation

takeWhile' :: (a -> Bool) -> [a] -> [a]

takeWhile' _ [] = []
takeWhile' f (x:xs)
	| f x = x : takeWhile' f xs
	| otherwise = []

dropWhile

This is the opposite of the previous function:

> dropWhile (==1) [1,1,2,2,3,3]
> [2,2,3,3]

You can also use functions:

> dropWhile (\ x -> x < 10 && x > 0) [1,2,3,10,4,5]
> [10,4,5]

Implementation

dropWhile' :: (A -> Bool) -> [a] -> [a]

dropWhile' _ [] = []
dropWhile' f (x:xs)
	| f x = dropWhile' f xs
	| otherwise = x:xs

takeWhile & dropWhile Example

This function splits up the words in a string into a list of strings containing no spaces.

split_words "" = []
split_words string =
	let
		first = takeWhile (/= ' ') string
		up_to_space = dropWhile (\= ' ') string
		after_space = dropWhile (== ' ') up_to_space
	in
		first : split_words after_space

> split_words "one two		three"
> ["one","two","three"]

words

The function that was made in the last example has a standard implementation called words.

unwords

This is the companion function to words. They aren’t quite inverses as unwords will put spaces inbetween each word.

zipWith

This function zips two lists together using a function:

> zipWith (+) [1,2,3] [4,5,6]
> [5,7,9]

> zipWith (\ x y -> if x then y else -y) [True, False, True] [1,2,3]
> [1,-2,-3]

Implementation

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]

zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys

Examples

mult_by_pos list = zipWith (*) list [0..]

> mult_by_pos [1,2,3]
> [0,2,6]
interleave str1 str2 = 
	let
		zipped = zipWith (\ x y -> [x,y]) str1 str2
	in
		concat zipped

> interleave "abc" "123"
> "a1b2c3"

In this example concat is used to make lists of strings into a single string.

Exercises

  1.  getNumber string = takeWhile (\ x -> elem x ['0'..'9']) string
    
  2.  wordCount string = length $ words string
    
  3.  numberWords string = zip $ words string $ [1..]