Haskell: Is there a way to infer the return type of the function from within the function?

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?

+6
source share
1 answer

You do not need a dummy variable, you can use the ScopedTypeVariables extension.

 {-# LANGUAGE ScopedTypeVariables #-} parse :: forall b. (Read b, Typeable b) => String -> IO b parse msg = case reads msg of [(value,"")] -> return value _ -> error $ "could not parse " ++ msg ++ " as " ++ show (typeOf (undefined :: b)) 
+12
source

Source: https://habr.com/ru/post/979859/


All Articles