Haskell:过滤列表与那些是整数

use*_*032 0 haskell list filter

我如何过滤列表,以便只返回整数列表?

例如,过滤列表就像[1, 1.2, 2, 2.2]返回一样[1, 2].

Sat*_*vik 6

考虑您的列表是类型,[Double]因为您不能(以任何简单的方式)具有不同类型的元素的列表.

一旦你有一个double列表,你可以使用该函数ceiling.

ceiling 2.1 = 3
ceiling 2.0 = 2
Run Code Online (Sandbox Code Playgroud)

因此,检查数字是否没有小数部分的函数可以写成

nonFractional d = (fromIntegral $ ceiling d) == d
Run Code Online (Sandbox Code Playgroud)

现在你可以对此进行过滤

> filter nonFractional [1, 1.2, 2, 2.2]
[1.0,2.0]
Run Code Online (Sandbox Code Playgroud)

(编辑)上述比较平等的方法不适用于大数字

> nonFractional  (12345678987654321.5)
True
Run Code Online (Sandbox Code Playgroud)

如果更改nonFractionalas 的定义,请使用@ David的想法

nonFractional d = (fromIntegral $ ceiling d :: Rational) == d
Run Code Online (Sandbox Code Playgroud)

然后它似乎也适用于大分数

> nonFractional  (12345678987654321.5)
True
Run Code Online (Sandbox Code Playgroud)


ДМИ*_*КОВ 5

首先,你的列表应该是同质的,所以你不能有Integers和列表Doubles.

有一个很好的函数properFraction,它将一个数字分解为整个和小数部分:

properFraction :: (Fractional a, Integral b) => a -> (b,a)
Run Code Online (Sandbox Code Playgroud)

因此,我们可以定义一个函数来计算出数字是否具有非零小数部分.

> let haveNoFractionalPart = (== 0.0) . snd . properFraction 
haveNoFractionalPart :: Double -> Bool
Run Code Online (Sandbox Code Playgroud)

不,我们可以使用该功能过滤您的列表:

> filter haveNoFractionalPart [1, 1.2, 2, 2.2]
[1.0,2.0]
Run Code Online (Sandbox Code Playgroud)

更新:

我应该承认,对于现实世界中的某些情况,我的解决方案无效且可行.因为像

> properFraction (11111111111111111111.1)
(11111111111111110656,0.0)
Run Code Online (Sandbox Code Playgroud)

无论如何,很难想象需要根据Integer你拥有的某些值列表来过滤你所调用的内容.并且没有这样的方法来定义具有浮点的任何数字具有零浮动部分,具有100%概率.

也许有些包装上IntegerDouble会有所帮助.