ghci - 默认混淆
ghci - defaulting confusion
我在检查不同整数类型的大小 (minBound
,maxBound
) 和 "length in decimal representation" 时碰巧看到了一些奇怪的行为。
使用 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
应该是 [=18] =] 通过显式类型注释 (:: [Int]
) - 并且通过引用透明度,所有名为 ma
的符号都应该相等。
如果我将上面的语句放在一个文件中并将其加载到 GHCi 中,我会得到正确的结果。
为什么我会得到错误的结果?
令人困惑的是,这仍然是单态性限制在起作用(或者更确切地说,在 GHCi 中缺少单态性限制)。由于 GHCi 没有启用单态性限制,因此您对 mi
和 ma
的定义不会像您认为的那样专门化为 Int
- 相反,它们保持通用 mi, ma :: Bounded a => a
并且 a
变量被实例化两次
- 在
fromIntegral $ length $ show ma
中作为 ()
一次(如您所见,这是默认设置)
- 曾在
[mi,ma,le] :: [Int]
中Int
如果您希望 mi
和 ma
实际上是 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]
我在检查不同整数类型的大小 (minBound
,maxBound
) 和 "length in decimal representation" 时碰巧看到了一些奇怪的行为。
使用 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
应该是 [=18] =] 通过显式类型注释 (:: [Int]
) - 并且通过引用透明度,所有名为 ma
的符号都应该相等。
如果我将上面的语句放在一个文件中并将其加载到 GHCi 中,我会得到正确的结果。
为什么我会得到错误的结果?
令人困惑的是,这仍然是单态性限制在起作用(或者更确切地说,在 GHCi 中缺少单态性限制)。由于 GHCi 没有启用单态性限制,因此您对 mi
和 ma
的定义不会像您认为的那样专门化为 Int
- 相反,它们保持通用 mi, ma :: Bounded a => a
并且 a
变量被实例化两次
- 在
fromIntegral $ length $ show ma
中作为()
一次(如您所见,这是默认设置) - 曾在
[mi,ma,le] :: [Int]
中
Int
如果您希望 mi
和 ma
实际上是 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]