У меня проблема, OCaml считает, что параметры a и s моей функции - это unit list, но они должны быть 'a list и string соответственно. Функция должна выводить элементы списка, разделенные заданным разделителем.

Результатом должна быть строка со следующим вводом: "This-is-label"

Постскриптум Я знаю о матче, но не могу его использовать

let rec function1 a s =
    if a = [] then failwith "Empty list" else 
    if List.tl a = [] then List.hd a else
    if List.tl a != [] then List.hd a; s; function1 List.tl a s
    ;;

function1 ["This"; "is"; "label"] "-";;
0
Ilya 23 Окт 2018 в 08:24

2 ответа

Лучший ответ

Кажется, вы ожидаете, что это выражение будет строкой:

List.hd a; s; function1 List.tl a s

Однако смысл оператора ; состоит в том, чтобы оценить выражение слева и затем игнорировать его значение. (Также считается плохим тоном, если тип не unit.) Затем оцените выражение справа, которое является значением выражения.

Таким образом, это выражение говорит, что нужно вычислить List.hd a, а затем забыть значение. Затем оцените s и забудьте значение. Затем оцените рекурсивный вызов.

Итак, первая проблема - собрать эти штуки в цепочку.

Оператор ^ объединяет две строки. Что-то вроде этого ближе к тому, что вы хотите:

List.hd a ^ s ^ function1 (List.tl a) s

Обратите внимание, что вам нужно заключить в скобки вызов List.tl. В противном случае это выглядит как два отдельных параметра для function1.

2
Jeffrey Scofield 23 Окт 2018 в 05:40

Проблема в вашем коде отсутствует () вокруг List.tl a в рекурсивном вызове. Также ^ необходимо использовать для объединения строк вместо ;. Код все еще очень необычный.

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

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

Две альтернативные реализации:

let rec join s = function
| [] -> "" (* or failwith "Empty list" if you insist *)
| [x] -> x
| x::xs -> x ^ s ^ join s xs

let join s a =
  let (res, _) =
    List.fold_left
      (fun (acc, sep) x -> (x ^ sep ^ acc, s))
      ("", "")
      a
   in
   res
0
Goswin von Brederlow 25 Окт 2018 в 15:20
52941681