**21 October 2018**

Copyright (C) 2018, H. Conrad Cunningham

Professor of Computer and Information Science

University of Mississippi

211 Weir Hall

P.O. Box 1848

University, MS 38677

(662) 915-5358

Professor of Computer and Information Science

University of Mississippi

211 Weir Hall

P.O. Box 1848

University, MS 38677

(662) 915-5358

**Browser Advisory**: The HTML version of this document requires use of a browser that supports the display of MathML. A good choice as of October 2018 is a recent version of Firefox from Mozilla.

I wrote this assignment description for CSci 450/503 Assignment #3 in Fall 2018.

Carrie, the Department’s Administrative Assistant, has a candy bowl on her desk. Often she fills this bowl with candy, but the contents are quickly consumed by students, professors, and staff members. In this project, we model the candy bowl.

At a particular point in time, the candy bowl may contain several different kinds of candy with zero or more pieces of each kind.

We can represent a candy bowl with the following user-defined Haskell algebraic data type `CandyBowl`

:

In this definition, type parameter `a`

denotes the type of the identifiers for the kinds of candy. For example, if we use strings for the kinds of candy, particular values might be `"Snickers"`

, `"Kiss"`

, and `"wintergreen mints"`

.

In this representation, if the bowl contains two `"Snickers"`

and nothing else, then the bowl would be represented by the following value:

We say that the bowl above contains no `"Kiss"`

pieces.

Note: There are several possible representations for the candy bowl. We could use an association list (i.e. a list of pairs mapping kinds to counts) or an implementation of `Data.Map`

to represent the candy bowl.

Develop a Haskell module with the following functions using the type `CandyBowl`

as defined above. You may use function you have completed to implement other functions in the list (as long as you do not introduce circular definitions).

In some cases, you may need to restrict the polymorphism on

`CandyBowl a`

to implement a function. But be careful not to restrict functions unnecessarily.You may find Prelude functions such as

`concatMap`

,`elem`

,`filter`

,`length`

,`map`

,`null`

,`replicate`

, and`span`

useful.You may also find functions in the

`Data.List`

library useful (e.g.`sort`

,`group`

,`(\\)`

).

`newBowl :: CandyBowl a`

creates a new empty candy bowl.`isEmpty :: CandyBowl a -> Bool`

returns`True`

if and only if the bowl is empty.`putIn :: CandyBowl a -> a -> CandyBowl a`

adds one piece of candy of the given kind to the bowl.For example, if we use strings to represent the kinds, then

adds one piece of candy of kind

`"Kiss"`

to the`bowl`

.`has :: CandyBowl a -> a -> Bool`

returns`True`

if and only if one or more pieces of the given kind of candy is in the bowl.`size :: CandyBowl a -> Int`

returns the total number of pieces of candy in the bowl (regardless of kind).`howMany :: CandyBowl a -> a -> Int`

returns the count of the given kind of candy in the bowl.`takeOut :: CandyBowl a -> a -> Maybe (CandyBowl a)`

attempts to remove one piece of candy of the given kind from the bowl (so it can be eaten). If the bowl contains a piece of the given kind, the function returns the value`Just bowl`

, where`bowl`

is the bowl with the piece removed. If the bowl does not contain such a piece, it returns the value`Nothing`

`eqBowl :: CandyBowl a -> CandyBowl a -> Bool`

returns`True`

if and only if the two bowls have the same contents (that is the same kinds of candy and the same number of pieces of each kind).`inventory :: CandyBowl a -> [(a,Int)]`

returns a Haskell list of pairs`(k,n)`

, where each kind`k`

of candy in the bowl occurs once in the list with`n > 0`

. The list should be arranged in*ascending order*by kind.For example, if there are two

`"Snickers"`

and one`"Kiss"`

in the bowl, the list returned would be`[("Kiss",1),("Snickers",2)]`

.`restock :: [(a,Int)] -> CandyBowl a`

creates a new bowl such that for any`bowl`

:`combine :: CandyBowl a -> CandyBowl a -> CandyBowl a`

pours the two bowls together to form a new “larger” bowl.`difference :: CandyBowl a -> CandyBowl a -> CandyBowl a`

returns a bowl containing the pieces of candy in the first bowl that are not in the second bowl.For example, if the first bowl has four

`"Snickers"`

and the second has one`"Snickers"`

, then the result will have three`"Snickers"`

.`rename :: CandyBowl a -> (a -> b) -> CandyBowl b`

takes a bowl and a renaming function, applies the renaming function to all the kind values in the bowl, and returns the modified bowl.For example, for some mysterious reason, we might want to reverse the strings for the kind names:

`f xs = reverse xs`

. Thus`"Kiss"`

would become`"ssiK"`

. Then`rename f bowl`

would do the reversing of all the names.