是否允许自由访问Haskell库中的内部中间函数?

k97glaaz  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(120)

我正在用Haskell语言编写一个数值优化库,目的是为库的用户提供梯度下降算法之类的函数。在编写这些相对复杂的函数时,我编写了中间函数,比如只执行一步梯度下降的函数。这些中间函数中的一些执行库的用户可能根本不需要的任务。有些甚至非常神秘。但是当被更大的函数使用时就有意义了。
通常的做法是将这些中间功能留给库用户使用吗?我考虑过将这些功能移到“内部”库,但是将小函数移到一个与使用它们的主函数完全不同的库中,对于代码的易读性来说似乎不是一个好主意。并且理想地希望在同一个地方测试这两者,所以这使得事情更加复杂。
我毫不奇怪地使用阴谋集团的图书馆,所以在这种情况下的答案,以及将是有益的,如果这是更容易。

fwzugrvs

fwzugrvs1#

你绝对不应该在你的包的 Backbone.js 模块的导出中把这样的内部函数和高级函数放在一起。这会使接口/haddock很难理解,如果用户依赖于在未来版本中很容易改变的低级细节,也会带来问题。
因此,我会将这些函数保存在一个“内部”模块中,“公共”模块会导入这些函数,但只会重新导出那些缩进使用的函数:

  • 公开
module Numeric.Hegash.Optimization (optimize) where
import Numeric.Hegash.Optimization.Internal
  • 专用
module Numeric.Hegash.Optimization.Internal where

gradientDesc :: ...
gradientDesc = ...

optimize :: ...
optimize = ... gradientDesc ...

一个更有争议的问题是,是否仍然允许用户加载Internal模块,也就是说,是否应该将其放在.cabal文件的exposed-modulesother-modules部分。因为总有一些你没有预见到的有效用例,这也使得测试更容易,只要确保你清楚地记录下模块是不稳定的就行了。只有那些在实现细节中非常深入以至于基本上不可能在模块之外使用的函数才不应该被公开。

643ylb08

643ylb082#

通过将函数列在标题中,可以有选择地从模块中导出函数。例如,如果有函数gradientgradient1,并且只想导出前者,则可以编写:

module Gradient (gradient) where

您也可以使用where将中间函数合并到它们的父函数中,以将作用域限制在父函数中。这也将防止内部函数被导出:

gradient ... =
  ...
  where
    gradient1 ... = ...

相关问题