5

minBound在检查不同整数类型的大小( , maxBound)和“十进制表示的长度”时,我碰巧看到了一些奇怪的行为。

使用 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默认为()因此 yield 2,但我不明白因为ma应该是一个Int显式类型注释 ( :: [Int]) - 并且通过引用透明性,所有命名的符号ma都应该是相等的。

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

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

4

1 回答 1

13

令人困惑的是,这仍然是单态性限制(或者更确切地说,在 GHCi 中缺乏单态性限制)。由于 GHCi 没有启用单态限制,因此您的定义mima没有Int像您认为的那样专门化 - 相反,它们保持通用,mi, ma :: Bounded a => a并且a变量被实例化两次

  • 一次(如您()所见fromIntegral $ length $ show ma,这是默认设置)
  • 一次如Int[mi,ma,le] :: [Int]

如果您想要mi并且ma实际上是 type 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]
于 2017-02-14T18:30:43.563 回答