I have a function that accepts some arguments and returns IO (Either String String), say
testEither :: Int -> IO (Either String String)
testEither 0 = return (Left "we got an error")
testEither _ = return (Right "everything is ok")
(Real function fetches some stuff from real world and might fail)
I want to send output from that function to writeFile fileName. Expected behavior: if I bind testEither 0 to writeFile "test.txt", I fail with Left ..., and if I call it with testEither 1, I get everything is ok in file test.txt.
I guess the type of the whole expression should be something like IO (Either String ()), but I may be wrong.
You can use the ErrorT1 monad transformer to give you pure error handling on top of the IO monad:
import Control.Monad.Error
testEither :: Int -> IO (Either String String)
testEither 0 = return (Left "we got an error")
testEither _ = return (Right "everything is ok")
main = runErrorT $ do
result <- ErrorT $ testEither 0
lift $ writeFile "test.txt" result
1 ErrorT appears to have been replaced with ExceptT in the newest version of mtl, but the functionality should be similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With