Search code examples
haskellfunctor

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


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

  • 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