假设我有以下函数:
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)它把一根线解析成我想要的任何东西。如果字符串格式错误,它将抛出一个显示消息的异常,该异常无法解析。
我在IO-Monad的do块中使用这个函数,如
(a,b) <- parse msg :: IO (Int,Int)在另一个地方,比如
s <- parse msg :: IO String现在,如果我想让异常更详细地报告它无法读取的类型
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))我怎么弄到有b型的东西?
一个可能的解决办法就是这样做。
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))并且调用它就像
s <- parse "" msg :: IO String但这看起来挺傻的。
有方法从函数内部推断函数的返回类型吗?
发布于 2014-12-18 13:38:53
您不需要虚拟变量,您可以使用ScopedTypeVariables扩展。
{-# 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))https://stackoverflow.com/questions/27547824
复制相似问题