[Haskell-cafe] Getting started

aditya siram aditya.siram at gmail.com
Mon Jul 5 11:43:00 EDT 2010


And here's a more sane version of recordSale:
recordSale' :: Title -> [Record] -> [Record]
recordSale' title sales =
  case (Prelude.lookup title sales) of
    Nothing -> error "This record does not exist"
    Just x -> [addSale (title,x)] ++ (filter (\a -> (getTitle a) /=
title) sales)

-deech

On Mon, Jul 5, 2010 at 11:39 AM, aditya siram <aditya.siram at gmail.com> wrote:
> 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 <Jackwaters89 at googlemail.com> wrote:
>>
>> 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 <aditya.siram at gmail.com>
>>> 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 <Jackwaters89 at googlemail.com>
>>>> 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 at 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 at haskell.org
>>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>>>
>>>>
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at 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 at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>


More information about the Haskell-Cafe mailing list