Hacker News new | ask | show | jobs
by getsat 5160 days ago
Can someone explain what is happening in this example? I'm learning Haskell right now and this makes no sense.
2 comments

    Prelude> :t 11111111111111111111111
    11111111111111111111111 :: Num a => a
    Prelude> :t (length [])
    (length []) :: Int
    Prelude> 11111111111111111111111111111 - (length [])
    1729917383
    Prelude> 1111111111111111111111111111 - 0
    1111111111111111111111111111
    Prelude> 1111111111111111111111111111 - fromIntegral (length [])
    1111111111111111111111111111
    Prelude> 11111111111111111111111111111 :: Int
    1729917383
"Int" is the machine-length integer type. "Integer" is the unbounded, but slower integer type ("bigint" in other languages). In Prelude, "length" always returns an Int, assuming that the length of a list will never be bigger than 232.

Haskell interprets numeric literals as the typeclass (Num a => a), meaning any member of the typeclass Num can be constructed using these literals. Int is one such type, and causes wraparound when it constructs an instance using the typeclass.

assuming that the length of a list will never be bigger than 232

Should be 2^32, of course. Though I think the real upper bound is (2^31)-1: there's a bit used for negative numbers, and there's zero.

It's essentially the same thing as doing:

    > 11111111111111111111111111111 :: Int
Numeric literals are automatically treated as Num instances, so when you subtract (length []) which is an Int, the literal is treated as an Int. In this case, it triggers an overflow condition, something that programmers understand well and have been dealing with from the earliest days.