By: Tom Sydney Kerckhove <syd@cs-syd.eu>
Give every fact its own module Hopinion.Facts was one module holding fourteen types and re-exporting four more, which is the shape that makes a dependency invisible. Everything wanting one fact imported all of them, so no file said which of them it needed, and a module that had come to depend on something unrelated could not be told from one that had not. Each type now lives in the module that gives it meaning, and no module re-exports another. A consumer names what it uses: the rule about concatenation imports Facts.Concat and Facts.Module and nothing else, where it used to import the lot. This costs import lines rather than saving them, 131 where there were 33, and that is the trade being made. What each of those lines says is now true, and a module's imports are a statement of what it is about rather than a single line that says nothing. Three things were hiding behind the re-exports and are now said outright. Hopinion.Compiled and the GenValidSpec rule both depend on the .hie reader, which reached them through Facts re-exporting Hopinion.Hie, so neither file mentioned it; both import it directly now. And validity-aeson was a dependency of the library only because Facts imported Data.Validity.Aeson for orphan instances that no Validity instance here needs. The import alone satisfied -Wunused-packages, so removing it took the dependency with it. NameFact is in Facts.Occurrence rather than in Facts.Name, where a name-shaped thing would seem to belong. It carries a Span and a ScopeKey, and Facts.Place already imports Facts.Name, so putting it there would have closed a cycle. The name it ended up with is the more honest one: it is an occurrence of a name rather than a name.