Haskell:读取一个数字(整数或浮点数)

mk1*_*k12 5 io parsing haskell input typing

我正在使用这个实现maybeRead:

maybeRead :: (Read a) => String -> Maybe a
maybeRead = fmap fst . listToMaybe . filter (null . dropWhile isSpace . snd) . reads
Run Code Online (Sandbox Code Playgroud)

和我自己的getNum功能,它提示直到它获得有效输入:

getNum :: (Num a, Read a) => String -> IO a
getNum s = do
    putStr s
    input <- fmap maybeRead getLine
    if isNothing input
        then getNum s
        else return $ fromJust input
Run Code Online (Sandbox Code Playgroud)

但是,如果我输入5.2它将其视为糟糕的输入 - 为什么?还有就是零个OCCURENCES IntInteger在我的代码.我只是用Num,因为我想接受任何类型的号码.

如果我明确地称之为getNum "Enter a number: " :: IO Double,那么它的工作原理.我必须这样做吗?Haskell的类型系统是不是让我觉得我应该能够在没有完全动态类型的情况下实现这一点时能够做到这一点?如果是这样,为什么我的代码甚至编译; 为什么它假设整数?

C. *_*ann 13

你的确函数会接受Integer,Float或任何其他Num实例.但是,它接受哪种类型,以及它所解析的扩展方式String,并不是由它接收输入决定的,而是根据你用它做什么确定结果的类型.

假设你使用getNum并将结果值传递给需要的东西Float; 在这种情况下,它将解析一个Float值.如果你把它传递给需要的东西Integer,它会解析它.

至于它为什么假设Integer,有一个"默认"系统用于Haskell报告中指定的模糊类型,并且规则说具有Num约束的模糊类型应该默认为Integer.

  • 啊.对不起,我误读了.无论如何,我所说的是在实践中很少需要添加*extra*约束或显式类型注释,因为最终你会将`getNum`的输出传递给需要特定类型的东西,类型推断将从那里. (4认同)