在我们的项目(一个带有可执行文件和库部分的阴谋集团项目(中,我们有时会实现标准函数的"更安全"或改进版本,例如base
并在新的命名空间中导出模块的调整版本,例如
module Data.Foo.Extended (module Data.Foo, foo) where
import Data.Foo hiding (foo)
foo = someSaferVersionOfFoo
这使我们能够使用更好的 API,而无需进行大的重构(我们可以在代码库的其他部分逐步迁移到Data.Foo.Extended
(。
但是,一旦我们决定移动到任何地方*.Extended
,我们希望在导入旧版(标准(模块时(或者使用某些功能时(发出警告,以便更改保持不变。
DEPRECATED
编译指示不起作用,因为我们不拥有要弃用的代码
有没有一种聪明的方法可以:
- 从项目中隐藏模块(我们的垫片除外(?
- 用我们自己的模块影子 ?
- 发出某种警告(即让
DEPRECATED
的想法起作用(?
Cabal 文件中的mixins
字段(我相信 Stack 也支持它(可用于重命名、隐藏或影子模块。
例如,假设我们有一个方便的库或带有MyPrelude
模块的包,我们可以通过以下方式影子另一个库的标准Prelude
:
library
-- in this library, Prelude is really MyPrelude
exposed-modules: Foo
hs-source-dirs: lib
default-language: Haskell2010
build-depends:
base ^>=4.12.0.0,
myprelude
mixins:
-- switcheroo happens here
base hiding (Prelude),
myprelude (MyPrelude as Prelude),
-- internal convenience library, could be an external package
library myprelude
-- MyPrelude uses Prelude normally, might even re-export it
exposed-modules: MyPrelude
hs-source-dirs: lib-prelude
default-language: Haskell2010
build-depends: base ^>=4.12.0.0
此外,可以将build-depends
和mixins
字段放入公共节中,以避免在多个可执行文件/库中隐藏同一模块时重复:
common tweaked-prelude
build-depends:
base ^>=4.12.0.0,
myprelude
mixins:
base hiding (Prelude),
myprelude (MyPrelude as Prelude),
library
import: tweaked-prelude
exposed-modules: Foo
hs-source-dirs: lib
default-language: Haskell2010