使用多个程序列出理解

时间:2018-05-08 14:31:14

标签: list haskell list-comprehension

我对haskell很新,并试图学习基础知识,现在我想试试 列表理解的一点点。

我想在0 to … number `mod` 13 == 3number `mod` 20 == 5中创建一个包含不均匀数字的列表(不是结尾)。

然后我想使用take函数并获取此列表的前5个数字 并告诉他们。

我的代码就是这样:

take 5 [x | x <- [0..], odd x == False, x > 0, x `mod` 13 == 3, x `mod` 20]

现在我在haskell中遇到错误,并且真的不知道该怎么做:

> <interactive>:14:19: error:  
    • No instance for (Num Bool) arising from the literal ‘0’  
    • In the expression: 0  
      In the expression: [0 .. ]  
      In a stmt of a list comprehension: x <- [0 .. ]  
<interactive>:14:25: error:  
    • No instance for (Integral Bool) arising from a use of ‘odd’  
    • In the first argument of ‘(==)’, namely ‘odd x’  
      In the expression: odd x == False  
      In a stmt of a list comprehension: odd x == False  

有人知道我怎么能正确地做到这一点吗?

3 个答案:

答案 0 :(得分:3)

罪魁祸首在于最后一部分:

take 5 [x | x <- [0..], odd x == False, x > 0, x `mod` 13 == 3, x `mod` 20]
--                                                              ^^^^^^^^^^

这里Haskell期望你编写一个过滤器,但是x `mod` 20 不是过滤器:它返回Bool,{{ 1}}返回与x `mod` 20本身相同的数字类型。

根据您的问题,您希望它为5,因此可以使用以下方法解决:

x

但这里还有其他一些问题:

  1. 你写了“不均匀”,因此take 5 [x | x <- [0..], odd x == False, x > 0, x `mod` 13 == 3, x `mod` 20 == 5] -- ^^^^^^^^^^^^^^^ 检查应该是odd x;
  2. True始终为x > 0,因为我们将True的迭代器限制为x;
  3. 我们可以将[1..]x <- [1..]合并到odd x;
  4. 这导致:

    [1, 3..]

    尽管如此,我们仍然不需要所有模数检查:我们可以先计算take 5 [x | x <- [1, 3..], x `mod` 13 == 3, x `mod` 20 == 5] (奇数约束),2和{{1}的最小公倍数这是20,结果我们知道结果中的数字是“跳”260。

    我们也知道第一个结果是13,因此可以重写为:

    260

答案 1 :(得分:3)

错误是因为x mod 20。这个表达式返回一个Num类型,你需要一个Bool。例如,如果要将模数结果与0进行比较:

take 5 [x | x <- [0..], even x, x `mod` 13 == 3, x `mod` 20 == 0]

答案 2 :(得分:1)

问题是

x mod 20
理解结束时

。您没有将它与任何内容进行比较,因此它无法作为过滤列表的条件。