Alexandre Lucchesi
Alexandre Lucchesi

Reputation: 725

Strange behaviour in GHCi

I wrote the following piece of code:

it :: Int -> Int
it n
    | n < 1     = error "Invalid entry."
    | n == 1    = 0
    | otherwise = 1 + it (n `quot` 2)

When I load it into GHCi, something weird happens. The first time I call the function it, it works fine and returns the expected results. However, the next time, I get the following crash:

λ: :t it
it :: Int -> Int
λ: it 2
1
λ: it 2

<interactive>:4:1:
    Couldn't match expected type `a0 -> t0' with actual type `Int'
    The function `it' is applied to one argument,
    but its type `Int' has none
    In the expression: it 2
    In an equation for `it': it = it 2
λ: :t it
it :: Int
λ: it
1

It seems that the type of it is being somehow modified after the first call. Things get even stranger when it is called multiple times from main, i.e. all the calls return the expected results, but in the end () is assigned as the type of it:

main :: IO ()
main = do
    let r1 = it 1
        r2 = it 2
        r3 = it 3
    print r1
    print r2
    print r3

λ: main
0
1
1
λ: :t it
it :: ()

I believe this is a bug related to the identifier it and GHCi internals, since renaming the function to something else (as it') completely solves the problem. Besides that, the body of the function appears to have no influence; doing let it = (+) 2 and evaluating it multiple times is also problematic.

Any insight would be appreciated. The output of ghci --version is "version 7.6.3".

Upvotes: 5

Views: 132

Answers (1)

&#216;rjan Johansen
&#216;rjan Johansen

Reputation: 18199

Bad luck in naming: it is the name GHCi automatically binds to the result of your previous evaluation, so that you can conveniently refer to it again. So your first use immediately rebinds it, shadowing your definition.

If it is defined in a module, you should still be able to refer to it reliably from GHCi with the module prefix, e.g. Main.it.

Upvotes: 11

Related Questions