Suppose I have the following function:
import Data.Typeable import Text.Read (reads) parse :: (Read b, Typeable b) => String -> IO b parse msg = case reads msg of [(value,"")] -> return value _ -> throwIO $ ErrorCall ("could not parse " ++ msg)
It parses the string into what I want. If the string is incorrect, it throws an exception that displays a message that could not be parsed.
I use this function in the do IO-Monad block, for example
(a,b) <- parse msg :: IO (Int,Int)
and elsewhere for example
s <- parse msg :: IO String
Now, if I want to make an exception a more detailed message whose type could not be read
import Data.Typeable import Text.Read (reads) parse :: (Read b, Typeable b) => String -> IO b parse msg = case reads msg of [(value,"")] -> return value _ -> throwIO $ ErrorCall ("could not parse " ++ msg ++ " as " ++ show ( typeOf something_that_has_type_b))
how do i get something that has type b?
A possible workaround would do this
import Data.Typeable import Text.Read (reads) parse :: (Read b, Typeable b) => b -> String -> IO b parse dummy msg = case reads msg of [(value,"")] -> return value _ -> throwIO $ ErrorCall ("could not parse " ++ msg ++ " as " ++ show ( typeOf dummy))
and calling him like
s <- parse "" msg :: IO String
But it looks pretty stupid.
Is there a way to infer the return type of the function from within the function?