弃用或隐藏第三方库中的模块或函数
Deprecate or shadow a module or function from a third-party library
在我们的项目(一个包含可执行文件和库部分的阴谋集团项目)中,我们有时会实现 "safer" 或标准函数的改进版本,例如base
并在新命名空间中导出模块的调整版本,例如
module Data.Foo.Extended (module Data.Foo, foo) where
import Data.Foo hiding (foo)
foo = someSaferVersionOfFoo
这使我们能够使用更好的 API 而无需进行大的重构(我们可以逐步转移到代码库其他部分的 Data.Foo.Extended
)。
但是一旦我们决定移动到 *.Extended
任何地方,我们希望有一种方法可以在导入遗留(标准)模块时(或者可能在使用某些功能时)发出警告,以便换棍子。
DEPRECATED
pragma 将不起作用,因为我们不拥有我们正在弃用的代码
有什么巧妙的方法可以:
- 从项目中隐藏一个模块(我们的 shim 除外)?
- 用我们自己的模块隐藏一个模块?
- 发出某种警告(即使
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 stanzas 以避免在多个 executables/libraries:
中隐藏同一模块时重复
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
在我们的项目(一个包含可执行文件和库部分的阴谋集团项目)中,我们有时会实现 "safer" 或标准函数的改进版本,例如base
并在新命名空间中导出模块的调整版本,例如
module Data.Foo.Extended (module Data.Foo, foo) where
import Data.Foo hiding (foo)
foo = someSaferVersionOfFoo
这使我们能够使用更好的 API 而无需进行大的重构(我们可以逐步转移到代码库其他部分的 Data.Foo.Extended
)。
但是一旦我们决定移动到 *.Extended
任何地方,我们希望有一种方法可以在导入遗留(标准)模块时(或者可能在使用某些功能时)发出警告,以便换棍子。
DEPRECATED
pragma 将不起作用,因为我们不拥有我们正在弃用的代码
有什么巧妙的方法可以:
- 从项目中隐藏一个模块(我们的 shim 除外)?
- 用我们自己的模块隐藏一个模块?
- 发出某种警告(即使
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 stanzas 以避免在多个 executables/libraries:
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