Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous type arising from try

Tags:

haskell

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.

like image 812
Elior Avatar asked May 06 '26 04:05

Elior


1 Answers

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.

like image 125
Random Dev Avatar answered May 11 '26 11:05

Random Dev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!