-- | Given a start point and a mapping from continutation labels to code
-- chunks, creates a single structure embedding the entire control flow.
-- The structure may be circular, but it will only take up a finite amount
-- of memory, and all continuation paths will only be computed once.
flow :: (Ord c) => System c b e a -> Flow b e a
flow sys = let
  flows = fmap toFlow $ systemPaths sys
  getFlow label = fromMaybe (error "flow: missing continue") $
    Map.lookup label flows
  toFlow g = case g of
    v :>> x      -> v :>> toFlow x
    Branch b x y -> Branch b (toFlow x) (toFlow y)
    Continue c   -> getFlow c
    End e        -> End e
  in toFlow $ systemStart sys
flow :: (Ord c) => System c b e a -> Flow b e a
flow sys = let
  flows = fmap toFlow $ systemPaths sys
  getFlow label = fromMaybe (error "flow: missing continue") $
    Map.lookup label flows
  toFlow g = case g of
    v :>> x      -> v :>> toFlow x
    Branch b x y -> Branch b (toFlow x) (toFlow y)
    Continue c   -> getFlow c
    End e        -> End e
  in toFlow $ systemStart sys
flow sys = let
  flows = fmap toFlow $ systemPaths sys
  getFlow label = fromMaybe (error "flow: missing continue") $
    Map.lookup label flows
  toFlow g = case g of
    v :>> x      -> v :>> toFlow x
    Branch b x y -> Branch b (toFlow x) (toFlow y)
    Continue c   -> getFlow c
    End e        -> End e
  in toFlow $ systemStart sys