CIS 554 Haskell 1: Exercises
Fall 2016, David Matuszek
Purposes of this assignment
- Get you started programming in Haskell
How to read type declarations
In the Haskell REPL,
:t thing will tell you the
thing. Here are some examples:
not :: Bool -> Bool
not is a function that, given a boolean value,
returns a boolean value.
head :: [a] -> a
head takes a list of some arbitrary type
and returns a value of type
mod :: Integral a => a -> a -> a
mod takes two values of type
must be an
Integral type, and returns a value of type
map :: (a -> b) -> [a] -> [b]
map takes a function from
b, and a list of
a, and returns a
Simple Haskell exercises
Write the following functions. Where built-in equivalents exist, do not
define a function in terms of the equivalent built-in function. For
example, don't say
let member = elem. (You can
elem in other definitions, though.)
The following functions can all be defined in a single line, so try to do
so. They do not need to work for infinite lists.
The following functions implement common set operations. At least some of
them can be written as a single line. Except for
member :: Eq a => a -> [a] -> Bool
- Returns true if the element occurs in the list.
count :: (Num a, Eq a1) => a1 -> [a1] -> a
- Counts the number of times a value occurs in a list.
forall :: (a -> Bool) -> [a] -> Bool
- Tests whether all elements of a list satisfy a given condition.
exists :: (a -> Bool) -> [a] -> Bool
- Tests whether any element of a list satisfies a given condition.
single :: (a -> Bool) -> [a] -> Bool
- Tests whether exactly one element of a list satisfies a given
mostly :: (a -> Bool) -> [a] -> Bool
- True if there are more elements in the list that satisfy the predicate
than elements that fail to satisfy the predicate.
you may assume that the lists are "sets," that is, contain no duplicate
isSet :: Eq a => [a] -> Bool
- True if the list contains no duplicate elements.
makeSet :: Eq a => [a] -> [a]
- Remove duplicate elements from a list.
subset :: Eq a => [a] -> [a] -> Bool
- True if every element in the first set also occurs in the second set.
equalSet :: Eq a => [a] -> [a] -> Bool
- True if the two sets contain the same elements (not necessarily in the
setDiff :: Eq a => [a] -> [a] -> [a]
- The set of values that are in the first set but not in the second set.
setUnion :: Eq a => [a] -> [a] -> [a]
- The set of values that are in either or both sets.
setIntersection :: Eq a => [a] -> [a] -> [a]
- The set of values that are in both sets.
Provide tests for the above functions. Haskell does not come with a
testing framework, and I would rather not ask you to download and install
one, so here's a very small framework for you to use.
And here is a brief example of its use:
assertTrue :: Bool -> String -> IO ()
assertTrue x claim = if x
then putStrLn claim
else putStrLn $ "*** Untrue: " ++ claim
assertFalse :: Bool -> String -> IO ()
assertFalse x claim = assertTrue (not x) claim
assertEqual :: (Eq a, Show a) => a -> a -> IO ()
assertEqual x y = if x == y
then putStrLn $ (show x) ++ " equals " ++ (show y)
else putStrLn $ "*** " ++ (show x) ++ " does not equal " ++ (show y)
main = do
assertTrue (member 3 [1, 2, 3, 4]) "3 is in the list [1, 2, 3, 4]"
assertFalse (member 7 [1, 2, 3, 4]) "7 is not in the list [1, 2, 3, 4]"
assertEqual 3 (count 'a' "abracadabra")
A small program
Write a program to read lines from the user, translate each line read into
the "-idig-" version of Gibberish, and print the result out to the user. See
in Wikipedia for the exact rules; since division into syllables is
somewhat complex, we will use a simplified version.
Our (simplified) rules for converting English to Gibberish are:
- A word of three or fewer letters is considered to have only one
- If a word begins with one of the five vowels
['a', 'e', 'i',
'o', 'u'], add
"idig" to the beginning of the
"idig" after each consonant cluster in the word,
except a consonant cluster that ends the word. Examples:
There are two other "clean up" rules:
Do not do any other cleanup. Don't worry about words that are all capitals,
punctuation marks inside words, punctuation marks at the beginning of a
- Retain initial capitalization. Examples:
- If a "word" ends with a punctuation mark, the modified word should end
with that punctuation mark.
If there are any ambiguities in how to translate to Gibberish, do whatever
makes sense to you, make a note of your decision in comments in your test
file, and make sure your tests enforce that decision.
Provide type declarations for all your functions, and unit tests for all
your non-I/O functions.
The Haskell functions
Your program is due to Canvas
before 11:59pm Tuesday, October 25.