Prologでreduce(l|r)
というわけでPrologで書いてみた。
reducel(Pred, [X|List], Result) :- reducel(Pred, X, List, Result). reducel(_, X, [], X). reducel(Pred, X, [Y|List], Result) :- call(Pred, X, Y, Z), reducel(Pred, Z, List, Result). reducer(_, [X], X). reducer(Pred, [X|List], Result) :- reducer(Pred, List, Y), call(Pred, X, Y, Result).
20分くらいかかっちゃってます。reducer
の方が簡単なんですよね。まだまだPrologは慣れないなぁ。
で、テスト。
?- reducel(pair, [1,2,3,4], R). R = [[[1, 2], 3], 4] ; No ?- reducer(pair, [1,2,3,4], R). R = [1, [2, [3, 4]]] ; No
大丈夫みたい。pair/3
の定義は以下。
pair(X, Y, [X, Y]).
あと、無名関数っぽくかけると楽なので、こんなの書いてみた。
:- op(1150, xfx, =>). =>(Vars, Term, Arg1, Arg2, Arg3) :- copy_term((Vars, Term), (Vs, T)), Vs = (Arg1, Arg2, Arg3), call(T).
さっきの例はこんな感じになる。
?- reducel((X,Y,Z => Z = [X,Y]), [1,2,3,4], R). R = [[[1, 2], 3], 4] ; No ?- reducer((X,Y,Z => Z = [X,Y]), [1,2,3,4], R). R = [1, [2, [3, 4]]] ; No
ぜんぜんPrologっぽくないけど気にしない気にしない。