如何显示 haskell 圆周率的更多位数?

How do I show more digits of haskell's pi?

我想要 take 前奏 pi 值的更多位数。

Prelude> take 4 $ show pi
"3.14"

但是

Prelude> take 17 $ show pi
"3.141592653589793"

Prelude> take 170 $ show pi
"3.141592653589793"

刚刚存储的 pi 常量是否被截断了? show 中是否有打印字符串更多数字的选项?

Pi 定义为

 pi = 3.141592653589793238

所以你可以拥有所有数字。请记住,Floating typeclass 用于表示它。

piFloating的一个方法 class:

class Fractional a => Floating a where
  pi :: a
  ...

所以pi是多态的,由实例的实现者适当地定义它。

最常见的实例是 FloatDouble,它们的精度有限:

Prelude> pi :: Float
3.1415927
Prelude> pi :: Double
3.141592653589793

但没有什么能阻止你使用其他软件包,比如 long-double 它在某些系统上提供了更多位:

Numeric.LongDouble> pi :: LongDouble 
3.1415926535897932385

rounded 通过 MPFR 软件实现给出任意多位精度:

Numeric.Rounded> pi :: Rounded TowardNearest 100
3.1415926535897932384626433832793
Numeric.Rounded> pi :: Rounded TowardNearest 500
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081283

numbers 包提供了构造性(精确)实数的纯Haskell 实现,可以根据需要显示任意多的数字:

Data.Number.CReal> showCReal 100 pi
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068"

您还可以使用 half 包降低精度,也许可以与 GPU 互操作:

Numeric.Half> pi :: Half
3.140625

当您评估 pi 而不给出特定类型时,解释器的默认规则开始发挥作用。

Each defaultable variable is replaced by the first type in the default list that is an instance of all the ambiguous variable’s classes. ... If no default declaration is given in a module then it assumed to be: default (Integer, Double) -- https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-790004.3.4

Prelude> :t pi
pi :: Floating a => a

Integer 不是 Floating,但 Double 是,因此通过默认为 Double 来解决歧义类型。您可以通过启用 -Wtype-defaults:

获取更多信息
Prelude> :set -Wtype-defaults 
Prelude> pi

<interactive>:2:1: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Double’
        (Show a0) arising from a use of ‘print’ at <interactive>:2:1-2
        (Floating a0) arising from a use of ‘it’ at <interactive>:2:1-2
    • In a stmt of an interactive GHCi command: print it
3.141592653589793

(注意:我编写了 long-double 包并且是 rounded 的当前维护者。)