It's good that you mention databases, because relational databases are designed specifically to solve such problems. A classic example from database theory is the problem with facts / objects, the problem of which is almost certain here: the account has separate elements, but sometimes we want to write reports that examine the elements without linking them to their accounts. The database or data structure that makes us go through invoices to get items makes us do too much work in these cases.
So one of your alternatives here will only be to use a relational database (there are lightweight built-in ones like SQLite, which might be the most suitable). Another alternative is to create a more relational-like design and model the problem as multiple relationships that can be related to each other in several ways - possibly using an index that speeds up the connection.
So, you can start with something like this, where the tracks are available at the top level of the collection (and therefore it’s easy to just search the tracks):
data MusicCollection = MC { tracks :: Set Track , albums :: Set Album , albumToTracks :: Album -> [Track] } data Track = Track { album :: Album, trackTitle :: String, tempo :: Maybe Int } deriving (Eq, Ord) data Album = Album { albumTitle :: String } deriving (Eq, Ord)
When you built the MusicCollection value, you will need to make sure that you are creating the albumToTracks function, which allows you to quickly get album tracks. (Or you can use Map Album [Track] instead of a function, the function is a bit more general.)
Another alternative that I have not developed, but perhaps worth paying attention to: a circular data structure in which tracks and albums refer to each other. You would have these data declarations:
data MusicCollection = MC { tracks :: Set Track, albums :: Set Album } data Track = Track { album :: Album, trackTitle :: String, tempo :: Maybe Int } deriving (Eq, Ord) data Album = Album { albumTitle :: String, tracks :: Set Track } deriving (Eq, Ord)
The question here, of course, is whether it is possible to “link the node” when you are building this data structure so that it can be finally presented. If you can do it, well, that would be great ...