我会问有用性.它是关于对已编译的可执行文件/库的大小的影响.不是代码可维护性或可读性.
导入特定模块
从包中导入唯一使用的模块而不是导入主模块(自己导入子模块)是否有用.
例如,使用Foreign模块(仅包含导入列表):
import Foreign.Storable
代替:
import Foreign
明确导入函数/类型
仅导入已使用的函数/类型而不是导入整个模块是否有用?
例如:
import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr)
代替:
import Foreign.ForeignPtr
最佳答案 如果模块被编译为目标文件,那么不,甚至在理论上也是如此.无法导入的功能仍可在内部使用,您可以在GHCI中加载模块并测试未导出的内部功能.
如果你是静态链接或使用泛型函数的特定实例,那么理论上编译器应该能够分析这个特定程序无法访问哪些库,并作为一个整体程序优化,将它们从可执行文件. (例如,如果程序使用的唯一列表是Int列表,则编译器可能只编译泛型函数的部分专用[Int]版本,并且只编译您使用的那些.)但是,它应该能够执行无论您如何声明导入和导出,都需要进行相同的静态分析作为整个程序优化.
在编译动态库时,理论上可以排除静态分析证明永远无法通过导出的接口进行任何可能的调用而直接或间接到达的代码路径或数据片段.如果是这样,编译器可以使用导出列表来证明库中的某些标识符完全无用,并将其从编译库中删除.
如果你问一些特定的编译器,比如GHC 8,我不知道.你必须测试它并看到.
专门列出您的导出和导入的主要好处是,多年后,当第二个模块声明您已经使用的标识符时,您将永远不会遇到麻烦.这件事发生在我之前,现在我更加小心了.