Ghci - promiscuous confusion

I happened to see some strange behavior when checking the size ( minBound , maxBound ) and the "length in decimal representation" of different integral types.

Using 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] ^ 

in last place I would expect 19 .

My first assumption is that maxBound defaults to () and therefore gives 2 , but I don't understand, because ma must be Int by explicit type annotation ( :: [Int] ) - and using referential transparency all characters named ma must be equal.

If I put the above expression into a file and upload it to GHCi, I get the correct result.

So why am I getting the wrong result?

+5
source share
1 answer

Vaguely, this is still a limitation of monomorphism in a game (or rather, its absence when in GHCi). Since GHCi has no restriction on monomorphism, your definitions of mi and ma do not become specialized for Int , as you think, they will be - instead, they remain generally like mi, ma :: Bounded a => a and the variables a are instantiated twice

  • once as () in fromIntegral $ length $ show ma (as you noticed, this is the default value)
  • once Int in [mi,ma,le] :: [Int]

If you want mi and ma really be of type Int , annotate them as such directly

 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] 

Or enable monomorphism restriction manually in 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] 
+13
source

Source: https://habr.com/ru/post/1264209/


All Articles