したがって、次のようなリストがある[1; 2; 3; 4; 5; 6]としましょう: 、関数の呼び出しごとに 2 つの要素をフォールドしたいとします。
したがって、関数を(1, 2)、(3, 4)、および(5, 6)の順に適用します。
そうするための関数での私の試みは次のとおりです。
let fold_left_multiple (func: 'a -> 'b list -> 'a) (base: 'a) (lst: 'b list) (items_per_fold: int): 'a * 'b list =
let (acc, remainder, _) = List.fold_left (fun (acc, cur_fold_acc, cur_num) el ->
if cur_num mod items_per_fold = 0 then (func acc (List.rev (el::cur_fold_acc)), [], 1)
else (acc, el::cur_fold_acc, cur_num + 1)
) (base, [], 1) lst in (acc, remainder)
これはある程度機能します。ただし、これの問題は、これらの要素を関数で使用するのが簡単ではないことです。
私の好みの実装では、タプルまたは配列を使用して、要素へのアクセスを容易にします。
utopこれは、(構文を使用して) より適切に期待される入力/出力の例です。この場合、要素の各ペアを合計しています。
# fold_left_multiple (fun lst (e1, e2, e3) -> (e1 + e2 + e3)::lst) [] [1; 2; 3; 4; 5; 6; 7; 8] 3;;
- : int list * int list = ([15; 6], [7; 8])
ここで、リストの長さが で割り切れない場合の残りの要素nは、タプルの 2 番目の要素に入れられます。
(この残りが解決策で逆になってもかまいません。)