+-- flattenBind ::
+-- HsFunction -- The signature to flatten into
+-- -> (CoreBndr, CoreExpr) -- The bind to flatten
+-- -> TranslatorState ()
+--
+-- flattenBind hsfunc bind@(var, expr) = do
+-- -- Flatten the function
+-- let flatfunc = flattenFunction hsfunc bind
+-- -- Propagate state variables
+-- let flatfunc' = propagateState hsfunc flatfunc
+-- -- Store the flat function in the session
+-- modA tsFlatFuncs (Map.insert hsfunc flatfunc')
+-- -- Flatten any functions used
+-- let used_hsfuncs = Maybe.mapMaybe usedHsFunc (flat_defs flatfunc')
+-- mapM_ resolvFunc used_hsfuncs
+
+-- | Decide which incoming state variables will become state in the
+-- given function, and which will be propagate to other applied
+-- functions.
+-- propagateState ::
+-- HsFunction
+-- -> FlatFunction
+-- -> FlatFunction
+--
+-- propagateState hsfunc flatfunc =
+-- flatfunc {flat_defs = apps', flat_sigs = sigs'}
+-- where
+-- (olds, news) = unzip $ getStateSignals hsfunc flatfunc
+-- states' = zip olds news
+-- -- Find all signals used by all sigdefs
+-- uses = concatMap sigDefUses (flat_defs flatfunc)
+-- -- Find all signals that are used more than once (is there a
+-- -- prettier way to do this?)
+-- multiple_uses = uses List.\\ (List.nub uses)
+-- -- Find the states whose "old state" signal is used only once
+-- single_use_states = filter ((`notElem` multiple_uses) . fst) states'
+-- -- See if these single use states can be propagated
+-- (substate_sigss, apps') = unzip $ map (propagateState' single_use_states) (flat_defs flatfunc)
+-- substate_sigs = concat substate_sigss
+-- -- Mark any propagated state signals as SigSubState
+-- sigs' = map
+-- (\(id, info) -> (id, if id `elem` substate_sigs then info {sigUse = SigSubState} else info))
+-- (flat_sigs flatfunc)
+
+-- | Propagate the state into a single function application.
+-- propagateState' ::
+-- [(SignalId, SignalId)]
+-- -- ^ TODO
+-- -> SigDef -- ^ The SigDef to process.
+-- -> ([SignalId], SigDef)
+-- -- ^ Any signal ids that should become substates,
+-- -- and the resulting application.
+--
+-- propagateState' states def =
+-- if (is_FApp def) then
+-- (our_old ++ our_new, def {appFunc = hsfunc'})
+-- else
+-- ([], def)
+-- where
+-- hsfunc = appFunc def
+-- args = appArgs def
+-- res = appRes def
+-- our_states = filter our_state states
+-- -- A state signal belongs in this function if the old state is
+-- -- passed in, and the new state returned
+-- our_state (old, new) =
+-- any (old `Foldable.elem`) args
+-- && new `Foldable.elem` res
+-- (our_old, our_new) = unzip our_states
+-- -- Mark the result
+-- zipped_res = zipValueMaps res (hsFuncRes hsfunc)
+-- res' = fmap (mark_state (zip our_new [0..])) zipped_res
+-- -- Mark the args
+-- zipped_args = zipWith zipValueMaps args (hsFuncArgs hsfunc)
+-- args' = map (fmap (mark_state (zip our_old [0..]))) zipped_args
+-- hsfunc' = hsfunc {hsFuncArgs = args', hsFuncRes = res'}
+--
+-- mark_state :: [(SignalId, StateId)] -> (SignalId, HsValueUse) -> HsValueUse
+-- mark_state states (id, use) =
+-- case lookup id states of
+-- Nothing -> use
+-- Just state_id -> State state_id