这取决于您从哪里获得数据。
Haskell 不允许您将纯整数与非整数混合,
所以你的整数会被Double等数据类型固有的不准确性所污染,除非你使用更准确的东西,比如Rational,
但鉴于您无论如何都不想要非整数,如果可以的话,在它们成为数字数据之前将它们从源头丢弃。
- 如果您从用户那里获取数据,请使用仅允许他们输入数字序列的输入表单,或使用下面的
getInt。
- 如果您从数据库或其他基于文本的来源获取数据,请使用下面的
getInt。
- 如果您从某些您无法控制的代码(库或外部调用)中获取数据,是否有替代方案只为您提供整数?
如果是,请使用它,如果不是,请在其他答案中使用其他基于舍入的解决方案之一。
getInt 将 String 转换为 Integer,巧妙地忽略任何不是 Integer 的内容:
import Data.Char (isDigit)
getInt :: String -> Maybe Integer
getInt xs | all isDigit xs = Just (read xs)
| otherwise = Nothing
所以getInt "12345" 是Just 12345 而getInt 12345678987654321.1 是Nothing。
我们可以使用它从某个列表中删除非整数输入:
getInts :: [String] -> [Integer]
getInts xss = catMaybes $ map getInt xss
或者更简洁地说,我们可以写成
getInts = catMaybes.map getInt。
现在catMaybes :: [Maybe a] -> [a],它摆脱了Nothings 并解开Justs。我们需要在顶部
import Data.Maybe (catMaybes) 获取它。
如果您的数据以某种浮点数的形式出现,
请记住,浮点类型中没有真正的相等性,
因此,即使您在检查之前转换为更准确的表示,
从逻辑上讲,您永远不可能知道原始数据是否
表示一个精确的整数或只是一个非常接近整数的东西
浮点表示在数据到达您之前四舍五入。
例如:
Prelude> (12345678987654321.6 :: Double) == 12345678987654322.0
True
而
Prelude> (12345678987654321.6 :: Rational) == 12345678987654322.0
False
但如果您可以选择数据类型,则您可以控制生成代码,因此请选择不包含非整数!
总结:在将非整数转换为数值数据之前, 最容易去除它们,
而且您不会偶尔出现奇怪的舍入错误。