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

如何在Relude中实现将[a]转换为[(a,a)]的pairs函数?

适配Relude的pairs函数实现方案

针对你需要实现pairs :: [a] -> [(a, a)]的需求,由于Relude默认不导出普通列表的tail(仅支持NonEmpty a类型),这里提供几种可行的适配方案:

方案1:显式导入普通列表的tail

Relude出于安全性考量,默认不导出会在空列表抛出异常的普通列表tail,但你可以从Relude.List模块显式导入它,保持原实现逻辑:

import Relude.List (tail)

pairs :: [a] -> [(a, a)]
pairs x = zip x (tail x)

⚠️ 注意:这个版本和标准Prelude的实现一样,传入空列表时会抛出异常,如果你需要安全处理空列表,建议选择其他方案。

方案2:手动实现无依赖版本(避开tail)

直接通过模式匹配实现,完全不依赖tail,同时天然处理空列表和单元素列表的情况:

pairs :: [a] -> [(a, a)]
pairs [] = []
pairs [_] = []
pairs (x:y:xs) = (x, y) : pairs (y:xs)

这个版本效率高,且没有异常风险,是最稳妥的纯手动实现方式。

方案3:利用NonEmpty做安全兼容

如果想利用Relude的NonEmpty类型保证安全性,同时兼容原有的[a]输入类型,可以通过viaNonEmpty转换后处理:

import Relude (NonEmpty(..), viaNonEmpty)

pairs :: [a] -> [(a, a)]
pairs = maybe [] (\(x :| xs) -> zip (x:xs) xs) . viaNonEmpty id

这里viaNonEmpty id将普通列表转为Maybe NonEmpty a,非空时拆分为首元素和剩余列表,再通过zip生成配对;空列表直接返回空,完全避免异常。

如果可以接受调整函数类型为NonEmpty a -> [(a, a)],实现会更简洁:

import Relude (NonEmpty(..), tail, toList)

pairsNE :: NonEmpty a -> [(a, a)]
pairsNE xs = zip (toList xs) (tail xs)

再包装一个兼容普通列表的函数:

pairs :: [a] -> [(a, a)]
pairs = maybe [] pairsNE . viaNonEmpty id

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:11:16