A Haskell 2010 report (language definition) says :
The program value is the value of the main identifier in the main module, which should be a calculation of type IO ฯ for some type ฯ . When the program is executed, the calculation of main is equal and its result (of type ฯ ) is discarded.
Your main function is of type IO (IO ()) . The above quote means that only external action is evaluated ( IO (IO ()) ), and its result ( IO () ) is discarded. How did you get here? Let's look at the type print <$> :
> :t (print <$>) (print <$>) :: (Show a, Functor f) => fa -> f (IO ())
So the problem is that you used fmap in combination with print . Considering the definition of Functor instance for IO :
instance Functor IO where fmap fx = x >>= (return . f)
you can see that this made your expression equivalent (head <$> getArgs >>= return . print) . To accomplish what you originally planned, simply remove the unnecessary return :
head <$> getArgs >>= print
Or, equivalently:
print =<< head <$> getArgs
Note that IO actions in Haskell are similar to other values โโ- they can be passed and returned from functions, stored in lists and other data structures, etc. An IO action is not evaluated if it is not part of the main calculation. To "glue" the actions of the IO together, use >> and >>= , not fmap (which is usually used to display pure functions over values โโin a certain "field" - in your case, IO ).
Please also note that this should not be related to lazy evaluation, but purity is semantically, your program is a pure function that returns a value of type IO a , which is then interpreted by the runtime system. Since your internal IO action is not part of this calculation, the runtime system simply discards it. A good introduction to these problems is the second chapter of Simon Payton Jones, "Shooting a Clumsy Squad . "
Mikhail Glushenkov
source share