The expression you are forcing is ((print "hi") >>= (
-> return ()))
, which is of type IO ()
. As such it represents an IO action. But evaluating such a thing is quite different from running it!
Evaluating a value means performing just enough steps to turn it into what is called weak head normal form. Because IO
is abstract, it is a bit tricky to see what that means in this case, but one can think of IO a
as RealWorld -> (a, RealWorld)
, and then the weak head normal form is, well, a function waiting to be given the RealWorld
.
Running implies evaluation, but also passes the RealWorld
as an argument, thus causing the IO
effect to happen.
All this is not very specific to IO
; your confusion and the concepts apply equally to a -> b
. If you understand what $!
does when the second argument is a function, you’ll understand what happens when it is an IO action.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…