不清楚为什么 Data.Ratio 中的函数没有公开以及如何解决

bde*_*caf 5 haskell module numeric module.exports

我正在使用Data.Ratio连分数的收敛)实现一个算法。但是,我遇到了两个障碍:

  • 该算法从分数开始1%0- 但这会引发零分母异常。
  • 我想模式匹配构造函数 a :% b

我正在探索hackage。一个特别是似乎正在使用这些功能(例如定义infinity = 1 :% 0,或模式匹配numerator)。

作为初学者,我也很困惑在哪里确定(%)numerator等暴露给我,但不是infinity(:%)

我已经使用整数元组做了一个肮脏的解决方法,但是为如此微不足道的事情重新发明轮子似乎很愚蠢。也很高兴了解如何阅读公开哪些功能的源代码。

lef*_*out 6

它们的导出并不是为了防止人们做这样的事情。看,类型

data Ratio a = a:%a
Run Code Online (Sandbox Code Playgroud)

包含太多值。特别是,例如2/63/9实际上是相同的数字?并且都由 表示1:%3。因此,2:%6实际上是一个非法值,果然,1:%0. 或者它可能是合法的,但所有函数都知道如何对待它们,因此2:%6对于所有可观察的手段都等于1:%3——我实际上不知道 GHC 选择了这些选项中的哪一个,但无论如何这是一个实现细节,可能会在未来的版本中改变不知不觉中。

如果库作者自己将这些值用于例如优化技巧,那是一回事——他们毕竟可以完全控制可能出现的任何算法细节和任何未定义的行为。但是如果用户必须构造这样的值,就会导致代码脆弱。

所以-如果你发现自己有首发的算法1/0,那么你应该确实不使用Ratio在所有的存在,但简单地存储分子和分母在一个普通的元组,其中有没有这样的问题,而只会使最终结果Ratio%

  • 有人建议(大约 30 年前)允许 1%0、-1%0 和 0%0 表示无穷大、-无穷大和 NaN。但这个想法被 Joe Fasel(他为 Haskell 编写了所有原始库)拒绝了,因为那时 Rational 将不再是一个领域。不过,有时它会很有用。 (3认同)
  • 导出的内容始终标记在_模块头_中。在这种情况下,[`模块 Data.Ratio (Ratio, Rational, (%), ...) where`](https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data .Ratio.html)。另请注意,最初定义此内容的底层模块“GHC.Real”确实导出了“:%”和“infinity”,但该模块被标记为“Stability:internal”,而“Data.Ratio”被标记为“Stability:stable” 。 (2认同)