
Ketil Malde wrote:
A module may be defined in a file with a name corresponding to the module name, or any dot-separated prefix of it? I.e. the file Foo/Bar.hs will define module Foo.Bar and optionally Foo.Bar.Baz as well?
GHC should then be able to find it, and I believe it already has a prioritized search mechanism (presumably, the file could be named Foo.Bar.hs, too).
I don't think GHC actually allows that (Foo.Bar.hs, ever). But your suggestion could work. 1. Try Foo/Bar/Baz.hs ; if it exists, end search (and error if it does not contain Foo.Bar.Baz, obviously as the file's top-level module). 2. Try Foo.Bar.hs ; if it exists, end search (and error if it does not contain Foo.Bar.Baz, obviously as a sub-module). 3. Try Foo.hs ; if it exists, end search (and error if it does not contain Foo.Bar.Baz, obviously as a sub-module... or possibly as a sub-sub-module?). 4. give up :-) Note though, that local modules tempt us to a couple other things too, even though they're not necessary to the proposal and would complicate it: - access-controlled modules (e.g. if other code can't import Foo.Bar.Baz) - relative-path imports / module names (e.g. if in Foo/Bar.hs we make Baz and try to import it some way with "import Baz") and as we already mentioned, it would likely involve some implicit importing of the sub-module. translating into ordinary haskell: I think my module-search mechanism makes a well-defined, deterministic way to find the right module, no complex translation necessary (except layout rule madness maybe?). Implicit importing: submodule syntax implies adding an "import The.Module.Name" line at that point in the containing file. This would suggest that submodules must be at the top, among the imports, because all imports must syntactically be at the beginning of the file -- and there's a reason for this. Bother! Even if the reason is dependency chasing, one would think same-file dependencies aren't important, but the submodules themselves can import things from other files, so those lines should need to be near the beginning anyway. so an example could be module MyData ( module MyData.Sub, -- or equivalently, D(..) transform ) where module MyData.Sub --or "module Sub" ?? that seems a bit too ad-hoc though where data D = E | F transform :: D -> D transform F = E transform E = F ~Isaac