[Haskell-cafe] Getting started

Holger Siegel holgersiegel74 at yahoo.de
Thu Jul 1 16:55:06 EDT 2010

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

More information about the Haskell-Cafe mailing list