loadTexture :: String -> IO (Either String GL.GLuint)
loadTexture filename = do
p <- PNG.loadPNGFile filename
oglLoadImg p
where
oglLoadImg :: (Either String PNG.PNGImage) -> IO (Either String GL.GLuint)
oglLoadImg (Left e) = return $ Left e
oglLoadImg (Right png) = do
... I need todo IO stuff in here
The code above seems really bloated and nasty. What can I do to make it simpler?
You essentially want a combination of the
Either emonad and theIOmonad. That’s what monad transformers are for!In this case, you can use the
ErrorTmonad transformer which adds error handling usingEitherto an underlying monad, in this caseIO.This keeps the old interface, although it would probably be even nicer to use
ErrorTfor your function as well, and have the call torunErrorTin yourmainfunction.Monad transformers can take some getting used to, but they are very useful.