
Yes there are a few more problems. Instead of point out each one here
is some modified code that does compile. Compare it to what you have
and let me know if you have questions:
type Title = String
type Artist = String
type Sold = Int
type Record = (Title, (Artist, Sold))
testDatabase :: [Record]
testDatabase = [("Jack", ("Waters", 2))]
newRecord :: Record -> [Record] -> [Record]
newRecord record dbase = [record] ++ dbase
getTitle :: Record -> Title
getTitle (title,_) = title
addSale :: Record -> Record
addSale (title, (artist,sold)) = (title, (artist, sold + 1))
recordSale :: Record -> [Record] -> [Record]
recordSale r@(title, (artist,sold)) sales =
case (Prelude.lookup title sales) of
Nothing -> error "This record does not exist"
Just x -> [addSale r] ++ (filter (\a -> (getTitle a) /= title) sales)
addRecord :: IO Record
addRecord = do
putStrLn "Please enter a title: "
title <- getLine
putStrLn "Please enter an artist name: "
artist <- getLine
putStrLn "Please enter the number sales: "
sales <- getInt
return (title , (artist, sales))
where
getInt :: IO Int
getInt = getLine >>= return . read
On Mon, Jul 5, 2010 at 11:36 AM, Mrwibbly
I changed that line to say type Sales = Sales Record. But unfortunately it still fails to compile. Do you have any idea why this might be the case?
-Jack
aditya siram-2 wrote:
You said it didn't compile. I somehow missed that , sorry. -deech
On Mon, Jul 5, 2010 at 11:06 AM, aditya siram
wrote: Does this code compile? The line "type Sales = Sales Record" for instance is wrong - it should be "data Sales = Sales Record". Additionally "recordSale" returns an Int, not [Sales].
-deech
On Mon, Jul 5, 2010 at 10:50 AM, Mrwibbly
wrote: This really helped, but now I am trying to add a new track to the database using a menu but it won't compile. I have tried a lot of different things but to no avail.
When I get rid of the menu I am able to run, for example, newRecord "This Charming Man" "The Smiths" 1 []
This adds the data to an empty database but I can't seem to call newRecord again and add another record to the existing database.
Thanks for your help previously,
Jack
type Title = String type Artist = String type Sold = Int type Sales = Sales Record type Record = (Title, Artist, Sold)
testDatabase :: [Sales] testDatabase = [(Sales "Jack" "Waters" 2)]
--recordSale :: Sales -> String -> String -> Sales --recordSale title artist = (title, artist)
newRecord :: Record -> [Sales] -> [Sales] newRecord title artist sold dbase = (title, artist, sold):dbase
recordSale :: Record -> [Sales] recordSale record sales = sold + 1
main :: [Sales] -> IO() main dbase = do putStrLn "1 = Add a new record: " input <- getLine let x = read input :: Int if x == 1 then do putStrLn "Please enter a title: " title <- getLine putStrLn "Please enter an artist name: " artist <- getLine putStrLn "Please enter the number sales: " sales <- getInt newRecord (Sales title artist sales []) dbase
Holger Siegel wrote:
Am 01.07.2010 um 21:56 schrieb Mrwibbly:
I'm having real trouble starting this project. Basically I have to create a record store that store information about artists and albums and also the number of sales that they have had. It also needs to generate a list of the top 5 sellers.
So far I have: recordSale :: Sales -> String -> String -> Sales
where recordSale sales anArtist aTrack returns a modified version of the sales.
Any help getting started on this would be gratefully received. I don't want answers, I just want help getting started.
First, I would state explicitly what a record is: It is a tuple of an artist's name and a record's name
type Record = (String, String)
Now function recordSale has type
recordSale :: Sales -> Record -> Sales
This is the an "uncurried" equivalent of your definition. You can read it as "from a sales object you get to another sales object via a (sold) record". That already seems to be a good abstraction, but we can do better: If you flip the arguments, you get
recordSale :: Record -> Sales -> Sales
Now you can create a sale (recordSale ("Zappa", "Apostrophe")). This sale is a function of type (Sales -> Sales) that modifies your sales. We state this by defining
type Sale = Sales -> Sales
recordSale :: Record -> Sale
Sales can be concatenated with the dot operator (.) and there is even a "neutral sale", the function 'id'. Thus, you know immediately that for any sales x,y,z there is (x . (y . z) == (x . y) . z) and (x . id == x). In other words, it forms a monoid - just like the number of sales together with (+) and 0!
If you're only interested in the number of sales, you can simply define
type Sales = Integer
recordSale record sales = sales + 1
But you don't want to keep track of the whole number of sales - you want a number for every record you have sold. That means, you need a data structure that maps records to their number of sales:
import Data.Map
type Sales = Map Record Integer
It's a bit tricky to find an implementation for recordSale. Think of how you can combine two arbitrary Sales objects before you try to implement it.
Regards, Holger
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://old.nabble.com/Getting-started-tp29046956p29073993.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://old.nabble.com/Getting-started-tp29046956p29077121.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe