> For an example of a project which I worked on for months, given N molecular graphs, find the maximum common subgraph which is in at least M of them. I did all that in Python. I don't think static types would have made a difference.
Even with no knowledge of the problem space, I can think of a whole bunch of static types off the top of my head.
You've already given your input type: N molecular graphs, and a number M.
You've also given your output type: the maximum common subgraph which is in at least M of the given N molecular graphs.
Straight away I can spot a problem with this, since there are no programs of this type. In particular, there is no valid output when M > N. Hence I would refine the input type to ensure that M <= N.
Since it appears in your input type, it would be useful to have a type for "molecular graph". Likewise, based on your output type, it would probably be useful to have types for "subgraph of g", "common subgraph of gs", "maximum common subgraph of gs" and "subset of gs".
Naively, I'd give your program a type something like this:
(m : Nat, gs : Set MolecularGraph, m <= size gs) -> (hs : SubSet gs, size hs >= m, MaximumCommonSubgraph hs)
Programming with type constraints like these would be very different to using Python, where you'd have no guarantee that a value is even a graph, let alone a maximum common subgraph of the input set.
Whether it would be more or less appropriate for your situation is, of course, an entirely separate issue ;)