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

寻求Haskell concat函数的Prolog等价实现,处理特定嵌套列表拼接

实现Haskell concat风格的Prolog嵌套列表拼接

你要的其实不是完全展平整个列表,而是针对嵌套列表的每一层子列表做拼接——把每个内部的小列表合并成一个,最终得到外层保留原层级、内层为拼接后列表的结果。针对你给出的例子[[[a],[b]],[[c],[d]]] → [[a,b],[c,d]],我来给你两种实用的实现方式:

方式一:自定义递归谓词

先写一个辅助谓词append_all/2,用来把一个列表中的所有子列表依次拼接成一个列表;再写主谓词concat_sublists/2,遍历外层列表的每个元素,对每个元素调用append_all并收集结果:

% 空列表的基准情况
concat_sublists([], []).

% 处理非空列表:对第一个子列表做拼接,递归处理剩余部分
concat_sublists([Sublist | Rest], [FlatSublist | RestFlats]) :-
    append_all(Sublist, FlatSublist),
    concat_sublists(Rest, RestFlats).

% 把列表中的所有子列表拼接成一个列表
append_all([], []).
append_all([Current | Remaining], Result) :-
    append_all(Remaining, TempResult),
    append(Current, TempResult, Result).

测试这个谓词:

?- concat_sublists([[[a],[b]],[[c],[d]]], Result).
Result = [[a, b], [c, d]] ;
false.

方式二:用内置谓词简化

Prolog的foldl和maplist可以让代码更简洁。foldl(append, Sublist, [], Flat)会把Sublist里的所有子列表从左到右依次拼接到空列表上,正好实现append_all的功能;再用maplist把这个操作应用到外层列表的每个元素上:

concat_sublists(List, Result) :-
    maplist(append_sublists, List, Result).

append_sublists(Sublist, Flat) :-
    foldl(append, Sublist, [], Flat).

同样测试:

?- concat_sublists([[[a],[b]],[[c],[d]]], Result).
Result = [[a, b], [c, d]].

这个版本更紧凑,利用了Prolog的高阶谓词,可读性也不错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:06:19