Reputation: 73
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.
Upvotes: 3
Views: 255
Reputation: 52280
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.
Upvotes: 8