I am trying to do a little error handling when opening a file, to be sure that the file exists/is readable. Here's my attempt :
init struct = do
str <- try $ readFile (filePath struct)
case str of
Left exception -> print exception
Right content -> execute content struct
(Struct is a data structure where I keep my file path and other variables). I get this error:
Ambiguous type variable ‘a0’ arising from a use of ‘try’ prevents the constraint ‘(Exception a0)’ from being solved. Probable fix: use a type annotation to specify what ‘a0’ should be.
But I just don't understand how to fix it.
it's because the result of try :: ... -> IO (Either e a) has a type-parameter for the exception e and you just put this into print which can handle all sort of stuff (as long as the e is in Show) - so it's not obvious to the compiler what type the intermediate e needs to be.
This is very similar to show . read - that should have type String -> String but what is read supposed to do? Read a Int, a Float - something different?
Easiest way to fix this is IMO with an type-application:
{-# LANGUAGE TypeApplications #-}
init struct = do
str <- try @IOException $ readFile (filePath struct)
case str of
Left exception -> print exception
Right content -> execute content struct
Of course you can add the type annotation wherever you want:
str <- try $ readFile (filePath struct) :: IO (Either IOException MyStruct)
etc.
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