I'm not an expert on type systems, but I don't think it would add that much in your case. You might get more out of it if you wanted by using phantom types, which is just a way to differentiate among structurally identical types, like this:
reduceGraph :: Graph a -> Graph Reduced
Now you can't pass unreduced graphs to functions where you expect some sort of an already reduced graph, and you could encode as much invariants as you wanted in your types, but yea, in cases where there are homogenous types with little variance (machine learning, statistics, your use case) static typing won't probably bring that much (unless you go nuts with dependant typing I guess).