在检查不同整数类型的大小(minBoundmaxBound)和“十进制表示长度”时,我偶然发现一些奇怪的行为。

使用GHCi:

Prelude> :{
Prelude| let mi = minBound
Prelude|     ma = maxBound
Prelude|     le = fromIntegral $ length $ show ma
Prelude|  in [mi,ma,le] :: [Int]
Prelude| :}
[-9223372036854775808,922372036854775807,2]
                                         ^

最后,我期望19

我的第一个猜测是maxBound默认为()并因此产生2,但是我不明白,因为ma应该是由显式类型注释(Int)组成的:: [Int],并且通过引用透明性,所有命名为ma的符号都应该相等。

如果将上面的语句放在文件中并将其加载到GHCi中,则会得到正确的结果。

那么为什么我得到一个错误的结果呢?

最佳答案

令人困惑的是,这仍然是发挥作用的单态性限制(或者在GHCi中缺少这种限制)。由于GHCi没有启用单态性限制,因此您对mima的定义不会像您认为的那样专门用于Int-而是像mi, ma :: Bounded a => a一样保持通用,并且a变量被实例化两次

  • 曾经作为()中的fromIntegral $ length $ show ma(如您所观察到的,这是默认设置)
  • 曾经是Int中的[mi,ma,le] :: [Int]

  • 如果您希望mima实际上是Int类型,请直接将其注释为
    Prelude> :{
    Prelude| let mi, ma :: Int
    Prelude|     mi = minBound
    Prelude|     ma = maxBound
    Prelude|     le = fromIntegral $ length $ show ma
    Prelude|  in [mi,ma,le]
    Prelude| :}
    [-9223372036854775808,9223372036854775807,19]
    

    或在GHCi中手动打开单态限制
    Prelude> :set -XMonomorphismRestriction
    Prelude> :{
    Prelude| let mi = minBound
    Prelude|     ma = maxBound
    Prelude|     le = fromIntegral $ length $ show ma
    Prelude| in [mi,ma,le] :: [Int]
    Prelude| :}
    [-9223372036854775808,9223372036854775807,19]
    

    关于haskell - ghci-默认困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42233527/

    10-13 06:04