【问题标题】:How to create an error message when input value is Float type and not Integer type in Haskell当输入值是浮点类型而不是 Haskell 中的整数类型时如何创建错误消息
【发布时间】:2019-03-30 04:38:45
【问题描述】:

对于一项学校作业,我的任务是创建一个确定一年是否为闰年的函数。

以下是我目前所拥有的。例如,当我输入“days_in_Year 2018”时,它会返回“非闰年”。此功能仅适用于整数值输入。我需要一些额外的代码,当输入值为双精度或浮点值时将返回错误消息。

days_in_Year :: Integer -> String
days_in_Year year
 | year `mod` 400 == 0 = "Leap Year"
 | year `mod` 100 == 0 = "Non-Leap Year"
 | year `mod` 4 == 0   = "Leap Year"
 | otherwise = "Non-Leap Year"

当输入为双精度或浮点值时,我希望我的函数能够返回“无效输入”...

【问题讨论】:

  • 您的输入验证需要在您输入的地方进行,您没有向我们展示。它不能进入​​这个功能;太晚了!
  • 您在类型注解中指定了Integer 输入,因此如果您尝试传递其他任何内容,编译器已经给您一个无效的错误。

标签: haskell error-handling floating-point integer


【解决方案1】:

Haskell 的主要优点之一是类型系统强制区分“纯”函数和“不纯”函数。你所拥有的是一个纯函数——你承诺给它一个Integer,并且该函数承诺总是给你一个好的结果(没有错误)。 (这些承诺由编译器按照合同强制执行,即在编译时,因为 Haskell 是一种静态类型语言。)这使得代码更容易推理。虽然您确实需要处理如果用户输入行为不当会发生什么,并且可以修改函数(以及它的类型签名)来这样做,但最好将该代码放在其他地方 - 比如您解析用户输入的地方.

这引出了一个问题,您如何获得用户输入,例如IntegerFloatDouble?一个简单的模式类似于例如。

import Text.Read

main = do
    s <- getLine
    case readMaybe s of
        Nothing -> putStrLn "Please enter an integer"
        Just x -> putStrLn $ days_in_Year x

这里,因为x 是作为days_in_Year 的参数提供的,所以编译器知道您正在尝试将字符串s 读取为Integer,如果它不能读取(例如,因为s == "5.0"),那么它只会返回Nothing,你可以告诉用户出了什么问题。

【讨论】:

  • 非常感谢!我很抱歉,但我是 haskell 的新手,我不太确定如何将它直接实现到我的代码中......你能不能告诉我?
  • @LaurensMellink 我编辑了它,应该是getLine 而不是readLn 抱歉。
  • 虽然函数实际上是纯粹的,但在这里并不重要。关键是 Haskell 是静态类型的,这意味着 编译器 将捕获任何将非Integer 值作为参数传递给days_in_Year 的尝试,而不是必须检测类型的函数在运行时传递给它的值。
  • @chepner 我认为这很重要。您是说修复了函数类型,编译器会捕获任何传递错误参数类型的尝试,因此错误发生在编译时。我的主观观点是,检测错误输入的运行时错误属于不同的函数(尽管您可以修改函数以接受字符串并在此处进行错误处理,但不应该这样做!因此函数应该保持纯净)。
  • @chepner 也许我有点混淆了这两者,为了清楚起见进行了编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-05
  • 1970-01-01
  • 2021-12-12
  • 2020-06-19
  • 2012-02-07
相关资源
最近更新 更多