Imagine I want to write an application which deals with podcast feeds. To store the parsed information from such a feed, I would write something like this:
data Podcast = Podcast {
podcastTitle :: String, -- ^ title of podcast
episodes :: [Episode] -- ^ list of episodes of podcast
... -- ^ some other fields
} deriving (Show)
data Episode = Episode {
episodeTitle :: String, -- ^ title of episode
podcast :: Podcast -- ^ podcast this episode belongs to
... -- ^ some other fields
} deriving (Show)
The above data record definitions reflect a common 1:n relation between data types: A podcast has many episodes and the episode belongs to one podcast. Now I have problems defining such podcast: Do define a Podcast
I already need the list of Episodes but to define an Episode
entity I need the Podcast
entity. It seems to me, that solving this cyclic dependency is impossible in haskell...
I also think that the above code is a relict from my programming in other languages. In the above style I would do it for example in python, but this programming language has a notion of state. In python I can first define a Podcast
entity without episodes, initialize then all episodes with the defined Podcast
entity and set then the episodes
field of the podcast to the list of episodes.
My question: What is the haskell way to model the 1:n relation between podcasts and episodes?
Answers to questions in the comments:
Why must an episode reference a specific podcast? It would be nice to have a function
podcast :: Episode -> Podcast
which returns the episode's podcast whenever I need it. I know, that one solution would be to pass also the Podcast
entity to each function for episodes, i.e. I replace each function
func1 :: Episode -> Something
where I would need the above podcast
function with
func1 :: Podcast -> Episode -> Something
It would be just great, to write as little code as possible and not to have the necessity to carry the Podcast
entity everywhere around.
Maybe I change my question a litte bit: It would be totally okay to define the Episode
data record without the podcast
field. How can implement
podcast :: Episode -> Podcast
in this case?
What if someone makes a podcast later on that includes episodes from other podcasts? In my case this will not happen and even if it is the case, it would be totally okay to consider the same episode as different ones. (In fact considering this issue would lift the 1:n relationship to an n:n relationsship, but the main question how to define those relationships in haskell remains the same).