> import IOutilities(getCookedLine, trim) > import Project2CSupport(leftCircularShift) explain purpose, retrieve data from file, initiate interaction > main = > do > putStr msgWelcome > carFile <- readFile "car.txt" > queryResults(lines carFile) retrieve queries from keyboard and send corresponding results to screen > queryResults carData = > do > putStr msgEnterQuery > queryString <- getCookedLine > if trim queryString == endDataSignal > then > putStr msgQuit > else > do > putStr(unlines( > [msgReply] ++ > [msgIndent ++ zipcode | > zipcode <- ownerZipcodes (words queryString) carData]++ > [msgEmptyLine])) > queryResults carData termination signal > endDataSignal = "quit" messages of interaction > msgWelcome = unlines[msgEmptyLine, > "Car-owner Zipcode Listings Service", > " (enter \"quit\" at any time to terminate)", > msgEmptyLine] > msgEnterQuery = unlines["Enter makes of cars of interest"] ++ > "all on one line, separated by spaces: " > msgReply = > unlines[msgEmptyLine, > "Zipcodes on file of owners of all cars of interest:"] > msgIndent = " " > msgQuit = unlines["Zipcode Service Terminated"] > msgEmptyLine = "" ... put definitions of other functions here ... deliver sequence containing zipcodes of all owners who own cars of all makes listed in carMakes > ownerZipcodes carMakes owners = > [(thirdFromLast . words) owner | > owner <- ownersOfAll carMakes owners] deliver sequence containing all owners who own cars of all makes listed in carMakes > ownersOfAll carMakes = > foldr1 (.) [ownersOf make | make <- carMakes] deliver all owners who own a car of given make > ownersOf make owners = > [owner | owner <- owners, > elementOf make [(nextToLast . words) owner, > (last . words) owner ]] elementOf x xs is True if x is an element of xs, False otherwise > elementOf x xs = xs /= (remove x xs) remove v xs is a sequence like xs, but without any elements equal to v > remove v xs = [x | x <- xs, x /= v] Individual Project 2A nextToLast[ ..., x, y, z] = y > nextToLast xs = (head . rightCircularShift . rightCircularShift) xs Individual Project 2B nextToLast[ ..., x, y, z] = x > thirdFromLast xs = (head . rightCircularShift . > rightCircularShift . rightCircularShift) xs Individual Project 2C rightCircularShift[a, b, c, ..., x, y, z] = [z, a, b, c, ..., x, y] > rightCircularShift xs = (reverse . leftCircularShift . reverse) xs test variables > carData = > ["Karen A Thorson, 112 Main, St Paul MN 55102 Ford Saab", > "John Shadley, 1601 S Shepherd, Houston TX 77019 Volkswagen Buick", > "William J T Harris, 2300 S Vandalia Av, Tulsa OK 74135 Honda Toyota", > "The Noellerts, 6650 Beach Blvd, Buena Park CA 90622 BMW Audi", > "Kathleen O'Donnell, 401 N Wabash, Chicago IL 60611 Ford Buick", > "Alastair James, 3100 Mass Av NW, Washington DC 20008 Rolls-Royce none", > "Barbara Maler, 1946 N Hillside, Wichita KS 67208 Honda Honda", > "Ozalp Babaoglu, 1024 Ramona, Palo Alto CA 94301 Toyota Honda"]