'Why doesn't fmap either error id over an Either work? [duplicate]

why does the following code not cause an error? Instead, it exits immediately.

someAction :: IO (Either String ())
someAction = return $ Left "Error"

main :: IO ()
main = either error id <$> someAction


Solution 1:[1]

When an action of type IO () is executed, its return value (the unit) is not evaluated:

  • In the interactive prompt: "GHCi will print the result of the I/O action if (and only if) [...] The result type is not ()."
  • When running a compiled program (I have verified this but can't find a reference! Feel free to edit in).

error, unlike ioError, is presenting as a pure function of type String -> a. To simplify your example:

main :: IO ()
main = pure $ error "error"

Running main as an IO action performs all side-effects (of which there are none) but doesn't do anything with the return value, so it is not evaluated.

This, however, will error, as print evaluates its argument (even ()):

main >>= print

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1