Fall 2016, David Matuszek

- Get you started programming in Haskell

In the Haskell REPL,` :t `

will tell you the
type of *thing*

. Here are some examples:*thing*

Type | Interpretation |
---|---|

`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 `a` ,
and returns a value of type `a` . |

`mod :: Integral a => a -> a -> a` |
`mod` takes two values of type `a` , which
must be an `Integral` type, and returns a value of type
`a` . |

`map :: (a -> b) -> [a] -> [b]` |
`map` takes a function from `a`
to `b` , and a list of `a` , and returns a
list of `b` . |

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

. (You can
use `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.

`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] -> Boo`

l- 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 condition.
`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.

`isSet`

and `makeSet`

,
you may assume that the lists are "sets," that is, contain no duplicate
elements.
`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 same order).
`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.

```
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)
```

And here is a brief example of its use:```
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")
```

Our (simplified) rules for converting English to Gibberish are:

- A word of three or fewer letters is considered to have only one syllable.
- If a word begins with one of the five vowels
`['a', 'e', 'i', 'o', 'u']`

, add`"idig"`

to the beginning of the word. Example:`"art"`

→`"idigart".`

- Put
`"idig"`

after each consonant cluster in the word, except a consonant cluster that ends the word. Examples:`"rabbit"`

→`"r`

",__idig__abb__idig__it`"schedule"`

→`"sch`

ed__idig__

ul__idig__

.

e"__idig__

There are two other "clean up" rules:

- Retain initial capitalization. Examples:
`"Sam"`

→`"S`

,__idig__am"`"Alice"`

→`"`

__Idig__al__idig__ic__idig__e". - 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 `words`

and `unwords`

may
be helpful.

Your program is due to Canvas
before **11:59pm Tuesday, October 25**.