This is a GHCi peculiarity briefly discussed here. When an expression is entered at the GHCi prompt and evaluated, if its type can be unified with IO a
, then it will be executed as an IO action with return type a
, and the return value of the action will be displayed (if it is other than ()
and if it has a Show
instance).
It turns out that the corresponding value of it
will be set to the return value of the IO action, rather than the IO action itself. I guess the idea is that, if you were to write:
> getLine
I typed this! <-- what I typed
"I typed this!" <-- the return value displayed
you'd want it
to give the returned value, not re-run the IO action:
> it
"I typed this!"
> :t it
it :: String
Specifically, in your case, the type of the expression:
> pure 5 :: Applicative t => t Integer
can be unified with IO Integer
, and so it is. The IO action is run, the return value is 5
, and that becomes both the output and the value of it
.
Note what happens if you write an expression that can't be unified with IO:
> pure 5 :: (Applicative t, Foldable t) => t Integer
[5]
Here, because IO
has no Foldable
instance in scope, the type can't unify with IO
, and instead GHCi's "extended defaulting" rules for assigning types to unspecified type variables are used. These extended rules include using the list type []
for unknown types of kind * -> *
, so we get pure 5 :: [Integer]
. If we first add a Foldable IO
instance, then unification with IO works again, and we get the behavior you already observed:
> instance Foldable IO -- this works, despite the warning
<interactive>:11:10: warning: [-Wmissing-methods]
• No explicit implementation for
either ‘foldMap’ or ‘foldr’
• In the instance declaration for ‘Foldable IO’
> pure 5 :: (Applicative m, Foldable m) => m Integer
5