Assignment #6


So now you have more capabilities for programming in ML and we want to have you exercise those abilities. For this assignment you will be playing with the idea of an inventory system similart to what we played with during class in Scheme, but I'm not going to have you bother writing a menu based system. This is in part because ML gives us the ability to use it and reuse names with val. It is also because I want you to do some work with files and to do that you will be writing a fair bit of file parsing code.

The idea of this assignment is that you will have files that represent inventories of items. You will also have those inventories in memory at times to work on them and be able to write them back out to files. You can pick the file format, just make sure that your code can read what it writes. In memory you can just store it as a list of tuples where a tuple represents a single item. This way an empty inventory can be represented by [] or nil. By the day this is due we will see how you might create your own types in ML to do this, but using tuples is sufficient for now since hopefully you won't attempt to write the code all on Friday after class. An item in the inventory should have a format as follows (name : string, quantity : int, purchasePrice : real, retailPrice : real).

You need to implement the following functions for this assignment. Please use exactly the function names and argument lists that I'm giving you here. I'm going to allow you to be sloppy for now and store money values in reals. Perhaps in a later assignment I'll change that.

addNewItem(inv,name,purchasePrice,retailPrice)
val addNewItem = fn : (string * int * real * real) list * string * real * real -> (string * int * real * real) list;
This function takes an inventory and the information on a new type of item and returns a new inventory where this item has been added with a quantity of zero.

purchaseItem(int,name,quantity)
val purchaseItem = fn : (string * int * real * real) list * string * int -> (string * int * real * real) list;
This function takes an inventory, a name, and a quantity and adds that many items to the quantity of the item and returns the new inventory for that.

sellItem(inv,name,quantity)
val sellItem = fn : (string * int * real * real) list * string * int -> (string * int * real * real) list;
This function takes an inventory, a name, and a quantity and subtracts that many items from the quantity of the item and returns the new inventory for that. If the quantity sold is greater than the quantity you have, an exception should be raised. The exception type should be InsufficientInventory of (string * int * real * real) list where the parameter is the inventory with that item type at quantity zero.

readInventory(fileName)
val readInventory = fn : string -> (string * int * real * real) list;
This obviously reads an inventory from file and returns it.

writeInventory(fileName, inv)
val writeInventory = fn : string * (string * int * real * real) list -> (string * int * real * real) list;
This should write the given inventory to a file and return that inventory.

accountInventories(oldInv,newInv)
val accountInventories = fn : (string * int * real * real) list * (string * int * real * real) list -> (real * real);
This is your one real processing function. It takes an old inventory and a new inventory and returns a tuple with two values in it. The first is how much money was spent buying items between the two (purchase price times any positive change in quantity) and the second is how much money was brought in from the sale of items (retail price times any negative changes in quantity). Any items not found in either inventory are assumed to have zero quantity.