<div dir="auto">Hello,<div dir="auto"><br></div><div dir="auto">Something like that was proposed multiple times, e.g. here:</div><div dir="auto"><a href="https://ghc.haskell.org/trac/ghc/wiki/Records/NestedModules" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/wiki/Records/NestedModules</a></div><div dir="auto"><br></div><div dir="auto">I personally like the idea a lot because it makes module system much more refactoring friendly. E.g. you can merge two modules into one file without renaming conflicting names as a step in a long refactoring chain. Or you can prototype in one file, and split the code into multiple modules later.</div><div dir="auto"><br></div><div dir="auto">Also, I think backpack has some limited support for multiple modules in one file. At least I saw something similar in backpack examples in Edward Yang's blog.</div><div dir="auto"><br></div><div dir="auto">Anyway I'd like to see your idea officially proposed via ghc-proposals.</div><div dir="auto"><br></div><div dir="auto">Thanks,</div><div dir="auto">Yuras.</div><br><div class="gmail_extra" dir="auto"><br><div class="gmail_quote">28 мар 2017 г. 0:14 пользователь "Aura Kelloniemi" <<a href="mailto:kaura.dev@sange.fi" target="_blank">kaura.dev@sange.fi</a>> написал:<br type="attribution"><blockquote class="m_6348730076302507176quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello<br>
<br>
I've been thinking about an extension to GHC which would allow creating new<br>
module-like namespaces within normal Haskell modules. Because this kind of<br>
namespacing system seems quite obvious to me, I ask if it has already been<br>
proposed or discussed in detail?<br>
<br>
The motivation:<br>
1. It would assist in solving the 'pollution of namespace' -problem, of which<br>
many Haskellers have complained.<br>
<br>
2. It would allow building bundles of related modules which can be exported<br>
from one module and then imported into others. This could result in<br>
radically fewer import statements.<br>
<br>
Rant:<br>
<br>
I'm tired of writing<br>
<br>
import qualified Data.ByteSstring as B<br>
import qualified Data.ByteString.Builder as B<br>
import qualified Data.ByteString.Lazy as BL<br>
import qualified Data.ByteString.Lazy.Builder as BL<br>
import qualified Data.HashMap.Strict as HM<br>
import qualified Data.Text as T<br>
import qualified Data.Text.Lazy as TL<br>
import qualified Data.Text.Lazy.Builder as BL<br>
<br>
A huge portion of this appears in almos all my Haskell source files. If I<br>
wrote my code in Python, I could condense all these imports to:<br>
<br>
<br>
So, you see, it was zero lines of code.<br>
<br>
I'm also tired of these patterns:<br>
(personName p), (companyName c), (objectName o), ... and I hardly<br>
prefer (name (p :: Person)), (name (c :: Company)) or (name (o ::Object))<br>
using the DuplicateRecordFields syntax.<br>
<br>
Proposal:<br>
<br>
I propose that modules can contain named submodules. They can be exported and<br>
imported just like anything else within a module, like this:<br>
<br>
{-# LANGUAGE Submodules #-}<br>
module Library.Things<br>
(qualified module Person,<br>
qualified module Company,<br>
personWorksInCompany<br>
) where<br>
<br>
-- import ...<br>
<br>
qualified module Person (Person (..)) where<br>
-- This is the module Library.Things.Person. Submodules could possibly<br>
-- use some other keywords than 'qualified module'. Maybe just 'module',<br>
-- 'submodule' or 'namespace'.<br>
data Person = Person {<br>
name :: {-# UNPACK #-} !T.Text,<br>
id :: {-# UNPACK #-} !Unique,<br>
...<br>
}<br>
<br>
-- Back in Library.Things<br>
qualified module Company where<br>
data Company = Company {<br>
name :: {-# UNPACK #-} !T.Text,<br>
employees :: {-# UNPACK #-} !V.Vector Unique,<br>
...<br>
}<br>
<br>
-- back in Library.Things again:<br>
<br>
personWorksIn :: Person.Person -> Company.Company -> Bool<br>
personWorksIn p c = Person.id p `elem` Company.employees c<br>
<br>
-- ... end of Library.Things<br>
<br>
And in another file:<br>
<br>
{-# LANGUAGE Submodules #-}<br>
<br>
-- The following demonstrates some ways of importing submodules. They are<br>
-- not meant to be used like this in real code:<br>
import Library.Things<br>
import qualified Library.Things as Things<br>
<br>
-- Now the submodules are also in scope and can be referred to like this:<br>
person1 :: Person.Person<br>
person2 :: Things.Person.Person<br>
company :: Library.Things.Company.Company<br>
<br>
-- And we also could have written: after importing Library.Things:<br>
import Person<br>
-- And now data type Person, selector name, etc. are in scope<br>
-- If we also imported the Company module:<br>
import Things.Company<br>
-- selector 'name' would now be ambiguous and need qualification at use site.<br>
<br>
-- Import lists would also work when bringing submodule contents to current<br>
-- namespace. Like this:<br>
import Library.Things hiding (module Company)<br>
-- or<br>
import qualified Library.Things (module Person)<br>
-- Which would allow Library.THings.Person.Person to be used requiring use of<br>
-- the fully qualified name.<br>
<br>
-- But the following would not work if Library.Things was not already<br>
-- imported:<br>
import Library.Things.Person<br>
-- because there is no such module, just submodule.<br>
<br>
-- ... end of other file<br>
<br>
Some projects probably would like to create a module like this:<br>
<br>
module Imports<br>
(qualified module B,<br>
qualified module HM,<br>
qualified module T<br>
) where<br>
<br>
import Data.ByteString as B<br>
-- ... and so forth ...<br>
<br>
Open questions:<br>
<br>
- Should there be a separate keyword for importing submodules, for example<br>
'use' or 'import namespace'?<br>
- Would imports be allowed within submodules? I'd say no for importing other<br>
modules, but importing submodules could be ok.<br>
- Would it be possible to extend submodules after their initial definition<br>
by just writing a new 'qualified module' block? I'd say yes, because<br>
submodules are just about namespacing. It is today possible to import<br>
many modules qualified and put them in the same namespace, like is often<br>
done.<br>
- What do you fellow Haskellers think about this all?<br>
<font color="#888888"><br>
--<br>
Aura<br>
______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.</font></blockquote></div><br></div></div>