+makeExpression :: [Function] Expression -> Expression
+makeExpression fs start
+ # (indices, graph) = foldr mkNode (newMap, emptyGraph) fs
+ = foldr mkExpr start $ scc $ foldr (mkEdges indices) graph fs
+where
+ mkNode :: Function (Map [Char] NodeIndex, Graph Function ()) -> (Map [Char] NodeIndex, Graph Function ())
+ mkNode f=:(Function l _ _) (m, g)
+ # (i, g) = addNode f g
+ = ('Data.Map'.put l i m, g)
+
+ mkEdges :: (Map [Char] NodeIndex) Function (Graph Function ()) -> Graph Function ()
+ mkEdges m (Function l i e) g
+ # ni = fromJust (get l m)
+ = foldr (addEdge ()) g [(ni, v)\\(Just v)<-map (flip get m) $ vars e []]
+
+ vars :: Expression [[Char]] -> [[Char]]
+ vars (Var v) c = [v:c]
+ vars (App l r) c = vars l $ vars r c
+ vars (Lambda l e) c = [v\\v<-vars e c | v <> l]
+ vars (Let ns e) c = vars e c // TODO
+ vars _ c = c
+
+ mkExpr :: (Graph Function ()) Expression -> Expression
+ mkExpr {nodes} e = Let [(l, foldr ((o) o Lambda) id i e)\\{data=(Function l i e)}<-elems nodes] e
+