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

如何用Haskell列表Monad实现生成全不同元素对的pairs函数

实现基于列表Monad的有序不同元素对函数

首先,我们来明确你的需求:你需要的是所有由列表中不同元素组成的有序对,也就是笛卡尔积中排除掉两个元素相同的情况。你原来的实现用了tails,只生成了原列表中x出现在y前面的对,所以缺少反向的组合。

下面是两种基于列表Monad的实现方式,分别用do表示法(更易读)和直接用>>=操作符:

方式1:使用do表示法(需要导入Control.Monad的guard)

import Control.Monad (guard)

pairs :: Eq a => [a] -> [(a,a)]
pairs xs = do
  x <- xs          -- 从列表中取出第一个元素x
  y <- xs          -- 从列表中取出第二个元素y
  guard $ x /= y   -- 过滤掉x和y相同的情况
  return (x, y)    -- 保留符合条件的有序对

方式2:直接使用>>=操作符

如果不想用guard,也可以直接通过条件判断返回空列表或单元素列表来实现过滤:

pairs :: Eq a => [a] -> [(a,a)]
pairs xs = xs >>= \x -> xs >>= \y -> if x /= y then [(x,y)] else []

工作原理说明

列表Monad的核心是>>=操作,它的作用是将列表中的每个元素映射为一个新列表,然后把所有新列表拼接起来。

  • 对于每个x,我们遍历整个列表取出所有y
  • 当x和y不同时,我们生成包含(x,y)的单元素列表;如果相同,则生成空列表(相当于过滤掉这个情况)
  • 最后所有符合条件的列表被拼接成最终的结果列表

验证示例

  • 输入pairs [1,2]会返回[(1,2),(2,1)]
  • 输入pairs [1,2,3]会返回[(1,2),(1,3),(2,1),(2,3),(3,1),(3,2)],完全符合你的预期。

内容的提问来源于stack exchange,提问作者Aelin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:37:13