如何使用过滤器从Haskell中的列表中过滤出特定数字的所有倍数

时间:2014-09-20 12:32:01

标签: haskell pointfree

我知道我可以创建一个函数来执行此操作但是我可以使用前奏中的过滤器函数。我可以使用

轻松过滤所有大于3的数字
filter (>3) [list]

但我想要像

这样的东西
filter (not (.. `mod` 4 == 0)) [list]

过滤掉所有四个倍数。我把..放在这里,因为我不知道那里有什么。有什么方法可以使用过滤器功能这样做,还是我应该自己做功能呢?提前致谢

3 个答案:

答案 0 :(得分:7)

你快到了那里:

filter (\n -> not (n `mod` 4 == 0)) [list]

读取\n" lambda n",并引入匿名函数。也就是说,给定n的函数测试它是否不是4的倍数。

否则,您可以使用" pointfree"样式,你可以在其中组成几个函数:

filter (not . (== 0) . (`mod` 4)) [list]

该函数读取为:取输入,将其缩小为模4,然后测试结果是否等于0,最后否定此类测试的结果。

请注意,您也可以使用/= 0代替== 0和否定。

答案 1 :(得分:3)

顺便说一句:ghc的最新版本有一个名为TypeHoles的扩展名,有时可以帮助那些“我把...放在这里因为我不知道那里有什么”的情况。

默认情况下,它在ghci中启用。如果您在代码中的表达式上留下_,ghc将尝试推断_中的内容可能具有哪种类型。

# :t filter _ [1,2,3,4]::[Int]

<interactive>:1:8:
    Found hole `_' with type: Int -> Bool
    In the first argument of `filter', namely `_'
    In the expression: filter _ [1, 2, 3, ....] :: [Int]

随着类型变得更加复杂,它变得更有帮助。

答案 2 :(得分:2)

使用lambda表达式:

filter (\x -> x `mod` 4 /= 0) list

或者,如果你喜欢冒险使用点自由风格:

filter ((/= 0) . (`mod` 4)) list

(我假设[]周围list是一个错误,您可能不希望只列出一个名为list的元素。)