首页 > 解决方案 > 弃用或隐藏第三方库中的模块或函数

问题描述

在我们的项目中(一个带有可执行和库部分的 cabal 项目),我们有时会从 eg 实现“更安全”或改进的标准函数base版本,并在新的命名空间中导出模块的调整版本,例如

module Data.Foo.Extended (module Data.Foo, foo) where
import Data.Foo hiding (foo)
foo = someSaferVersionOfFoo

这使我们能够使用更好的 API 而无需进行大的重构(我们可以逐步移至Data.Foo.Extended代码库的其他部分)。

但是,一旦我们决定迁移到*.Extended任何地方,我们希望在导入遗留(标准)模块时(或者可能在使用某些功能时)发出警告,以便更改生效。

DEPRECATEDpragma 不起作用,因为我们不拥有我们要弃用的代码

有没有聪明的方法:

标签: haskellghccabaldeprecation-warning

解决方案


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-dependsmixins字段放入公共节中,以避免在跨多个可执行文件/库隐藏相同模块时重复:

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

推荐阅读