【问题标题】:How to parse a float number input in Haskell?如何在 Haskell 中解析浮点数输入?
【发布时间】:2014-11-25 08:10:00
【问题描述】:

问题是我需要输入格式正确的十进制数,例如浮点数。 但是,我不知道如何解析输入以确保它真的是一个浮点数。如果没有,我需要把StrLn “ERR”。假设我有连续输入。

如下所示,我可以在 IF 之后添加什么条件来排除错误的输入格式,例如 1.2.e!@#$,我应该给出“ERR”并循环 main 而不是得到错误并立即退出程序。

input <- getLine
if (read input1 :: Float) > 1.0
    then do 
        let result1 = upperbound (read input :: Float)
        let result2 = lowerbound (read input :: Float)
        print result4
        print result3
        main
    else do 
        putStrLn"ERR"
        main

【问题讨论】:

    标签: haskell


    【解决方案1】:

    readpartial function - 它仅适用于输入域的子集。部分函数的一个更好的例子是head:它在非空列表上运行良好,但在空列表上会抛出错误——你只能在IO monad 中处理错误。部分函数在某些情况下很有用,但您通常应该避免使用它们。所以就像headread 是一个不安全的函数——当输入无法解析时它可能会失败。

    read 有一个安全的替代方案:readMaybe 来自 Text.Read

    readMaybe :: Read a => String -> Maybe a
    

    readMaybe 永远不会失败 - 如果它无法解析字符串,它将返回 Nothing。处理Maybe 值是一项简单的任务,可以通过多种方式完成(case 表达式、Data.Maybe 函数、do 表示法等)。下面是一个使用 case 表达式的示例:

    import Text.Read
    ...
    case (readMaybe input :: Maybe Float) of
      Just f | f > 1.0 -> ...
             | otherwise -> ...
      Nothing -> ...
    

    This article 有助于理解 Haskell 中不同的错误处理方式。

    【讨论】:

    • 你的方法对我的情况非常有效......你真的帮了我大忙......非常感谢!
    【解决方案2】:
    Prelude> let s1 = "1.223"
    Prelude> let s2 = "1"
    Prelude> let s3 = "1.2.e!@#$"
    Prelude> read s1 :: Float
    1.223
    Prelude> read s2 :: Float
    1.0
    Prelude> read s3 :: Float
    *** Exception: Prelude.read: no parse
    

    read 无法解析字符串时抛出异常。您需要处理该异常。

    【讨论】:

    • 谢谢,实际上我是haskell的新人。所以我尝试处理异常,但我无法弄清楚相应的异常类型。所以你能举个例子吗处理这个异常?
    • 实际上,在这种情况下,使用 Text.Read 中的 readMaybereadEither 会更简单。请参阅@Benesh 的回答。
    猜你喜欢
    • 1970-01-01
    • 2013-06-27
    • 2014-02-07
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多