List 根据索引从列表中选择元素

List 根据索引从列表中选择元素,list,prolog,List,Prolog,有没有一种方法可以定义一个行为(或多或少)如下的谓词: % nths(?Indices, ?List, ?Nths) nths([], _, []). nths([N|Ns], List, [E|Es]) :- nth0(N, List, E), nths(Ns, List, Es). 但是没有显式循环,没有lambda?我觉得应该可以用maplist或者findall来做,但是我想不出来 (当然,这仅适用于列表、整数索引[0,列表长度)和列表的所有第n个成员) 另一方面,这是

有没有一种方法可以定义一个行为(或多或少)如下的谓词:

% nths(?Indices, ?List, ?Nths)
nths([], _, []).
nths([N|Ns], List, [E|Es]) :-
    nth0(N, List, E),
    nths(Ns, List, Es).
但是没有显式循环,没有lambda?我觉得应该可以用
maplist
或者
findall
来做,但是我想不出来

(当然,这仅适用于列表、整数索引[0,列表长度)和列表的所有第n个成员)


另一方面,这是一个非常简短而明显的定义……

一个简单的
findall/3
就足够了:

nths(Ns, List, Es) :-
    findall(E, (member(N, Ns), nth0(N, List, E)), Es).
maplist
也可以这样做,但它需要一个辅助谓词:

nth0r(L, N, X) :- nth0(N, L, X).
nths(Ns, List, Es) :-
    maplist(nth0r(List), Ns, Es).

但此版本不能正确处理约束。即列表中出现的约束。@false:发布了一个带有
maplist/3
的版本。为什么不使用
findall
而不是
bagof
?它确实生成
[]
而不是失败,我们不需要关心自由变量。@WillNess:我认为自由变量需要
bagof
,但你是对的,
findall
也可以。特定的参数顺序不允许直接使用maplist/3。因此需要一个中间定义来重新定义对参数进行排序。库(lambda)避免了额外的定义。@false我对lambda有一种完全不合理的恐惧。我想从长远来看,克服它不会有什么坏处。如果索引是有序的,非递减的,这真的应该通过循环来完成-在列表上一次遍历。@WillNess否,索引是随机的(未知)顺序。索引和原始列表都不是太大,也不是一个性能问题。@Boris:似乎您有RigorLabda(sic),这正是在lambdas出现时让您感到震惊的疾病。我可以稍微理解一下:变量处理不同于函数式语言,因为变量在Prolog中的作用有所不同。