You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell列表推导式多条件无限列表生成报错求助

修复你的Haskell无限列表推导式问题

嘿,作为Haskell新手碰到这类问题太正常了,咱们一步步拆解你的代码问题,然后搞定它!

首先看你代码里的几个明显问题:

1. 语法错误:不完整的mod表达式

你写了x mod 20,但没给出判断条件(比如==5)——mod是二元运算符,返回的是整数,而列表推导式的过滤条件必须是布尔值,这直接导致了编译报错。

2. 逻辑矛盾:奇数判断搞反了

你写的odd x == False是在筛选偶数,但你明确要求元素是奇数,这完全和需求相反!其实这里甚至可以不用写odd x,因为x mod 20 ==5已经能保证x是奇数(20的倍数是偶数,加5后必然是奇数),当然如果你想明确加上,直接写odd x就行,不用加== True(Haskell里布尔值可以直接当条件用)。

3. 冗余的x>0条件

你从[0..]开始遍历,但满足x mod20 ==5的最小x是5,已经大于0了,所以这个条件完全可以去掉,保留也不影响,但没必要。

先验证你的条件是否有解

咱们用中国剩余定理确认一下,你要找的数需要满足:

  • x ≡3 mod13
  • x ≡5 mod20

设x=20k+5,代入第一个式子:
20k+5 ≡3 mod13 → 20≡7 mod13,5≡5 mod13,所以7k +5 ≡3 mod13 → 7k ≡11 mod13。
7在mod13下的逆元是2(因为7*2=14≡1 mod13),所以k≡11*2=22≡9 mod13,即k=13m+9。
代入回x的表达式:x=20*(13m+9)+5=260m+185。
所以最小的解是185,之后每次加260(13和20的最小公倍数)就能得到下一个解,所有解都是奇数,完全符合你的要求。

修正后的代码

首先是最贴近你原始写法的修正版本:

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

如果你想明确加上奇数判断(虽然冗余,但更清晰):

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

运行这段代码会得到前5个元素:[185,445,705,965,1225],你可以逐个验证:

  • 185 mod13 = 3,mod20=5,是奇数 ✔️
  • 445=185+260,加的是13和20的最小公倍数,所以mod13和mod20的结果不变,依然满足所有条件 ✔️

更高效的写法

如果你不想从0开始逐个过滤(毕竟要遍历185个数才找到第一个解),可以直接用我们推导出来的公式生成序列,性能更好:

take 5 [260*m + 185 | m <- [0..]]

这样直接生成符合要求的无限列表,不用过滤,取前5个元素的速度会快很多,尤其是当你需要取大量元素的时候。

内容的提问来源于stack exchange,提问作者Kubaguette The Testobun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:18:59