У меня возникла проблема моделирования структуры данных в Haskell. Предположим, что я работая в исследовательском центре для животных, и я хочу отслеживать мои крысы. Я хочу отслеживать назначение крыс клеткам и эксперименты. Я также хочу отслеживать вес моих крыс, объема моих клеток и вести заметки о моих экспериментах.
В SQL я могу сделать:
create table cages (id integer primary key, volume double);
create table experiments (id integer primary key, notes text)
create table rats (
weight double,
cage_id integer references cages (id),
experiment_id integer references experiments (id)
);
(я понимаю, что это позволяет мне назначать двух крыс из разных эксперименты в одну клетку. Это предназначено. Я фактически не запускаю исследовательский центр для животных).
Две операции, которые должны быть возможны: (1) с учетом крысы, найдите объем ее клетки и (2), учитывая крысу, получите примечания к эксперименту, к которому он принадлежит.
В SQL это будут
select cages.volume from rats
inner join cages on cages.id = rats.cage_id
where rats.id = ...; -- (1)
select experiments.notes from rats
inner join experiments on experiments.id = rats.experiment_id
where rats.id = ...; -- (2)
Как я могу моделировать эту структуру данных в Haskell?
Один из способов сделать это -
type Weight = Double
type Volume = Double
data Rat = Rat Cage Experiment Weight
data Cage = Cage Volume
data Experiment = Experiment String
data ResearchFacility = ResearchFacility [Rat]
ratCageVolume :: Rat -> Volume
ratCageVolume (Rat (Cage volume) _ _) = volume
ratExperimentNotes :: Rat -> String
ratExperimentNotes (Rat _ (Experiment notes) _) = notes
Но разве эта структура не представила бы кучу копий Cage
и Experiment
s? Или я просто не беспокоюсь об этом и надеюсь, что оптимизатор позаботится об этом?