Как использовать сложение на сложной функции в ocaml - PullRequest
0 голосов
/ 06 октября 2018

Как видно из названия, я хочу использовать сгиб.Если я правильно понимаю, раньше он применял функцию к каждому элементу в списке.Это то, что я хочу сделать с моей функцией, но я не знаю, как ее отформатировать.

Вот функция, которую я хочу использовать со сложением:

let pairing list =
let rec aux counter length paired list = match list with
| [] -> paired
| [head] -> paired
| head :: head' :: tail -> if counter = length then aux (counter-1) length ((head, head) :: paired) (head :: head' :: tail) else aux counter length ((head, head') :: paired) (head' :: tail)
in List.rev(aux (List.length(listheads list)) (List.length(listheads list)) [] (listheads list));;

Что она делаетэто возвращает список всех элементов в списке в паре вместе.

Например, если мой список [3;4;2], он должен вернуть

[(3,3); (3,4); (3,2); (4,3); (4,4); (4,2); (2,3); (2,4); (2,2)]

В настоящее время он возвращает только [(3,3); (3,4); (3,2)], поскольку функция применяется только к первому элементуиз списка.

Вот все вспомогательные функции:

let rec member list x = match list with
| [] -> false
| head :: tail -> head = x || member tail x

let head_list list =
let rec aux l1 list = match list with
 | [] -> l1
 | (x,y) :: tail -> aux (x :: l1) tail
in List.rev (aux [] list);;

let head'_list list =
let rec aux l2 list = match list with
 | [] -> l2
 | (x,y) :: tail -> aux (y :: l2) tail
in List.rev (aux [] list);;

let listheads list =
let rec aux returnlist l1 l2 = match l1 with
| [] -> returnlist
| head :: tail -> if member l2 head = true && member returnlist head = false then aux (head :: returnlist) tail l2 else aux returnlist tail l2
in List.rev(aux [] (head_list list) (head'_list list));;

Что делает listheads, это займет мой исходный список (скажем [(3,4); (4,2); (2,3); (4,7); (9,4)]), используйте head_list и head'_list вчтобы определить, какие целые числа находятся в позиции head и head' в кортеже, и поместить их в список (в случае, который я дал, [3;4;2]).

Я знаю, что foldпринимает в качестве аргументов функцию, пустой список и список, но я не знаю, как использовать сопряжение со сложением.

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Ваш код должен сделать двойной проход по списку

   let pairing l =
     let second_pass x acc y = ......  in
     let first_pass  acc el = .......  in
     List.fold_left first_pass [] l |> List.rev

Первая функция прохода должна вызывать функцию второго прохода, а вторая функция прохода создаст элемент пары.Свободен для завершения кода двух функций.

Вот результат, который я имею:

    utop # pairing [3 ; 4 ; 2];;
    - : (int * int) list =
    [(3, 3); (3, 4); (3, 2); (4, 3); (4, 4); (4, 2); (2, 3); (2, 4); (2, 2)]
0 голосов
/ 06 октября 2018

Очень сложно ответить на ваш вопрос, потому что нет чистого места, чтобы добавить складку, чтобы получить желаемый результат.

Возможно, будет более плодотворно просто отладить ваш код.Мне кажется, вы используете свой счетчик задом наперед.Его начальное значение - длина списка, и оно уменьшается для каждого рекурсивного вызова.Но ваш тест на завершение тестов против длины списка.Мне кажется, вы должны проверять 0 (или, возможно, 1).

Если у вас есть функция f, которая делает что-то интересное для значения, и у вас есть список значений, вы можете использоватьList.map, чтобы получить список значений f, примененных к каждому элементу списка.Для этого вам не нужно сгибать.

Цель сгиба состоит в том, чтобы вычислить нечто иное, чем просто список значений функции.Например, если каждый вызов f создает список значений, вы можете использовать сгиб, чтобы объединить эти списки в более длинный список.

Допустим, f превращает значение x всписок [x; x].Затем вы можете создать (перевернутый) двойной список примерно так:

let f x = [x; x]

let double l =
    let aux sofar x = f x @ sofar in
    List.fold_left aux [] l

# double [1;2;3];;
- : int list = [3; 3; 2; 2; 1; 1]

Вы могли бы следовать этому шаблону, если бы могли придумать функцию, подобную f, которая преобразует значение в список.Если вы определите f внутри вашей внешней функции, у нее будет доступ к начальному списку.

...