Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour in GHCi

Tags:

haskell

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".

like image 495
Alexandre Lucchesi Avatar asked Mar 23 '15 06:03

Alexandre Lucchesi


People also ask

How do I stop GHCi from running?

Quits GHCi. You can also quit by typing control-D at the prompt. Attempts to reload the current target set (see :load ) if any of the modules in the set, or any dependent module, has changed.

What does GHCi mean in Haskell?

GHCi [1] is GHC's interactive environment that includes an interactive debugger (see The GHCi Debugger). GHCi can. interactively evaluate Haskell expressions. interpret Haskell programs. load GHC-compiled modules.

Is GHCi an interpreter?

GHCi interprets the whole line as an expression to evaluate. The expression may not span several lines - as soon as you press enter, GHCi will attempt to evaluate it. In Haskell, a let expression is followed by in .


1 Answers

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.

like image 121
Ørjan Johansen Avatar answered Oct 27 '22 00:10

Ørjan Johansen