title: How do you manage an object graph in Haskell?
body: <p>I'm trying to re-learn systems analysis.  I've got a lot of object-oriented thinking for which I'm not able to find equivalents in Haskell, yet.</p>
  
  <p>A fictional system consists of Ambulance Stations, Ambulances and Crew.  (It's getting object-y already.)  All this state can be wrapped up in a big SystemState type.  SystemState [Stations] [Ambulances] [Crew].  I can then create functions which take a SystemState, and return a new SystemState.</p>
  
  <pre><code>module AmbSys
      ( version
      , SystemState
      , Station
      , Ambulance
      , Crew
      ) where
  
  version = "0.0.1"
  
  data SystemState = SystemState [Station] [Ambulance] [Crew] deriving (Show)
  
  data Station = Station { stName :: String
                         , stAmbulances :: [Ambulance]
                         } deriving (Show)
  
  data Ambulance = Ambulance { amCallSign :: String
                             , amStation :: Station
                             , amCrew :: [Crew]
                             } deriving (Show)
  
  data Crew = Crew { crName :: String
                   , crAmbulance :: Ambulance
                   , crOnDuty :: Bool
                   } deriving (Show)
  </code></pre>
  
  <p>Here's a ghci session where I create some data.</p>
  
  <pre><code>*AmbSys&gt; :load AmbSys                 
  [1 of 1] Compiling AmbSys           ( AmbSys.hs, interpreted )
  Ok, modules loaded: AmbSys.
  *AmbSys&gt; let s = Station "London" []                
  *AmbSys&gt; let a = Ambulance "ABC" s []               
  *AmbSys&gt; let s' = Station "London" [a]
  *AmbSys&gt; let c = Crew "John Smith" a False        
  *AmbSys&gt; let a' = Ambulance "ABC" s [c]   
  *AmbSys&gt; let s'' = Station "London" [a']             
  *AmbSys&gt; let system_state = SystemState [s''] [a'] [c]
  *AmbSys&gt; system_state                                 
  SystemState [Station {stName = "London", stAmbulances = [Ambulance {amCallSign = "ABC",
   amStation = Station {stName = "London", stAmbulances = []}, amCrew = [Crew 
   {crName = "John Smith", crAmbulance = Ambulance {amCallSign = "ABC", 
   amStation = Station {stName = "London", stAmbulances = []}, amCrew = []}, 
   crOnDuty = False}]}]}] [Ambulance {amCallSign = "ABC", amStation = Station {
   stName = "London", stAmbulances = []}, amCrew = [Crew {crName = "John Smith",
   crAmbulance = Ambulance {amCallSign = "ABC", amStation = Station {stName = "London",
   stAmbulances = []}, amCrew = []}, crOnDuty = False}]}] [Crew {crName = "John Smith",
   crAmbulance = Ambulance {amCallSign = "ABC", amStation = Station {stName = "London",
   stAmbulances = []}, amCrew = []}, crOnDuty = False}]
  </code></pre>
  
  <p>You can already see a couple of problems here:</p>
  
  <ol>
  <li>I have been unable to create a consistent SystemState - some of the values are 'old' values, such as s or s', rather than s''.</li>
  <li>lots of references to the 'same' data have separate copies.</li>
  </ol>
  
  <p>I could now create a function which takes a SystemState and a Crew member's name which  returns a new SystemState where that crew member is 'off-duty'.</p>
  
  <p>My problem is that I have to find and change the crew member in the Ambulance and the (identical copy of the) crew member in the SystemState.</p>
  
  <p>This is possible for small systems, but real systems have many more linkages.  It looks like a n-squared problem.</p>
  
  <p>I am very aware that I am thinking about the system in an object-oriented way.  </p>
  
  <p>How would such a system be correctly created in Haskell?</p>
  
  <p><b>Edit: Thanks to everyone for your answers, and those on reddit too <a href="http://www.reddit.com/r/haskell/comments/b87sc/how_do_you_manage_an_object_graph_in_haskell/" rel="noreferrer">http://www.reddit.com/r/haskell/comments/b87sc/how_do_you_manage_an_object_graph_in_haskell/</a> </b></p>
  
  <p>My understanding now seems to be that I can do the things I want in Haskell.  On the downside, it seems to be that object/record/struct graphs aren't 'first class' objects in Haskell (as they are in C/Java/etc.), because of the necessary lack of references.  There's just a trade off - some tasks are syntactically simpler in Haskell, some are simpler (and more unsafe) in C.</p>