通过过滤每两个数字的序列,使用理解力在Haskell中生成列表

时间:2019-04-19 10:32:19

标签: haskell functional-programming

我想使用理解力在haskell中执行以下列表:

[1,2,5,6,9,10,13,14,17,18]

我已经尝试过了:

[x | x <- [1..18], y <- [1..4], y < 3]

但是我明白了:

[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18]

我不知道我是否可以使用一些Enum函数来获取列表,但是我想知道是否有某种方法可以实现列表理解。我可以看到每个y值都得到一个x,但是我只希望y值进入过滤器,而不是第一代列表。

4 个答案:

答案 0 :(得分:4)

您可能想要这个:

Prelude> [x+y | x <- [1, 5..18], y <- [0..1]]
[1,2,5,6,9,10,13,14,17,18]

答案 1 :(得分:3)

尝试

[x | x <- [1..18], x rem 4 < 2]

编辑

正确的解决方案是

 [x + 1 | x <- [0..17], x `rem` 4 < 2]

答案 2 :(得分:1)

忽略列表理解,只是

-- [1,2,5,6,9,10,13,14,17,18] == [1,2] ++ [5,6] ++ [9,10] ++ ...
--                            == [1+0,1+1] ++ [5+0,5+1] ++ [9+0,9+1] ++ ...
concatMap (\x -> [x, x+1]) [1,5..18]

[1,5..18] >>= \x -> [x, x+1]

转换回列表理解后,您将获得@NetWave's answer(通过[1,5..18] >>= \x -> [0..1] >>= \y -> [x + y]

答案 3 :(得分:0)

它会在以前的值上重复添加1和3,因此列表理解可能不是最佳解决方案。您已经有了完美的答案。

这也很懒,通常更有用。

scanl (+) 1 $ cycle [1,3]

take 25 $ scanl (+) 1 $ cycle [1,3]

[1,2,5,6,9,10,13,14,17,18,21,22,25,26,29,30,33,34,37,38,41,42,45, 46,49]