I want to create data types for accessing and modifying a simple music library, consisting of albums consisting of tracks. For a basic idea, consider the following:
data MusicCollection = MC { albums :: Seq Album }
data Album = Album { albumTitle :: String, tracks :: Seq Track }
data Track = Track { trackTitle :: String, tempo :: Tempo }
data Tempo = Unknown | BPM Int
In addition to tempo, there may be other attributes like style or rating.
The above solution gives me fast access to random albums. Additionally, I’d like to have fast access to all tracks faster than a specified tempo. And again, it would be nice to have fast random access to the returned tracks:
fasterThan :: Int -> MusicCollection -> SomeRandomAccessCollection Track
Updating a track in the collection shouldn’t be too slow as well.
Question:
I don’t know if adding a Map Tempo (Seq Track) to the MusicCollection is best or if it’s possible to immitate relational data bases somehow. Perhaps there are completely different solutions?
I currently don’t want to use a data base, but it would be interesting to know criteria when to use them in desktop applications.
Yes,
Map Tempo (Seq Track)is a good choice here, especially since itsOrd-based structure lets you make queries like “all tracks with tempo greater than n” efficiently; cf. Data.Map.split.This basically is imitating relational databases by using an index.
You may also be interested in IxSet and HiggsSet (an intended successor to IxSet by a different author), which are intended to augment a set structure with various indexes, especially in tandem with a transactional serialisation system like acid-state. They support convenient comparison queries like greater than, less than, etc. If you only have one or two indices, though, it’s probably best just to roll your own.