Search code examples
haskellghci

Weird behavior of (^)


I'm working on a puzzle solving game in which an exponent function is required, so I define

exp' :: Int -> Int -> Int
exp' = (^)

Here happens the weird:

*Main> exp' 6 25

-8463200117489401856

But

*Main> 6^25

28430288029929701376

I couldn't find any difference between my exp' and (^) from ghci.

Is is a ghc bug?

The Glorious Glasgow Haskell Compilation System, version 8.0.1


Solution

  • I couldn't find any difference

    Yes, there are some differences.

    :t exp'
    exp' :: Int -> Int -> Int
    
    :t (^)
    (^) :: (Num a, Integral b) => a -> b -> a
    

    namely

    :t (^)
    --                           Num    Integral    Num
    (^) :: (Num a, Integral b) => a  ->     b    ->  a
    

    See? It's about the type.

    Simply put, Int is bounded so it can overflow to negative when exceeding allowed range:

    > (6::Int) ^ (25::Int)
    

    -8463200117489401856

    while Integer is unbounded, so does not overflow:

    > (6::Integer) ^ (25::Integer)
    

    28430288029929701376

    So, to fix it you just change Int to Integer:

    exp' :: Integer -> Integer -> Integer
    exp' = (^)
    

    You may want to visit https://www.haskell.org/tutorial/numbers.html for more details about types and Numbers.