Hacker News new | ask | show | jobs
by BadCRC 5160 days ago
I really hope Haskell/Snap starts getting picked up by everyday web developers so someone can start exposing ridiculous things like:

  > 11111111111111111111111111111 - (length [])
  => 1729917383
1 comments

Can someone explain what is happening in this example? I'm learning Haskell right now and this makes no sense.

    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.