2016-07-16 1 views
0

Я пытаюсь создать список уникальных, добавляя к списку, но я получаю эту ошибку.Добавление в список на основании условия в OCaml

Error: This expression has type 'a list 
     but an expression was expected of type unit 

in_list - это булева функция, которая проверяет, находится ли это значение в списке.

if(in_list x seen_list) then print_string("Already found") else [email protected] in 
    List.iter uniq check_list;; 

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

ответ

0

Это ошибка типа, а не синтаксическая ошибка.

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

В частности, если элемент уже есть, функция вызывает print_string, который возвращает (). Это называется unit и является заполнителем, не представляющим интересного значения. Когда элемент еще не существует, ваша функция возвращает значение типа 'a list. Почти наверняка, что вам нужно сделать, это вернуть список во всех случаях.

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

Update

Есть много вещей, чтобы исправить в этом коде, но в этом суть упражнения я полагаю.

Ваша следующая проблема заключается в том, что List.iter является императивной функцией, то есть хочет, чтобы сделал чем-то, а не дал результат. Следовательно, функция, которая выполняет итерацию по списку, должна возвращать единицу (описанную выше). Вместо этого вы используете функцию uniq, которая возвращает список.

Если вы хотите использовать функцию высшего порядка, как List.iter, который является отличным стилем OCaml, вам нужно будет использовать складку (List.fold_left или List.fold_right), целью которого является накопление результата.

+0

Какой тип это должно быть?Когда я меняю оператор печати на '[1; 2; 3]', он дает мне ошибку: это выражение имеет тип int list -> int list , но ожидалось выражение для типа int list -> unit Тип int list не совместим с блоком типа ' –

+0

Если вы хотите, чтобы ваша функция была полиморфной, вам нужно вернуть что-то того же типа, что и список ввода. Фактически, вы должны почти наверняка просто вернуть список входных данных для этого случая. Трудно быть уверенным, не видя всего вашего кода. –

1

TL; DR: Списки неизменны в OCaml

В соответствии с вашим кодом, вы, кажется, полагают, что списки изменяемые в OCaml, и они не являются. Следовательно, [email protected] вычисляет новый список, но не меняет seen_list.

Вы можете изменить свой код

let uniq seen_list x = 
    if in_list x seen_list then 
    (Printf.printf: "uniq: %d: Already seen.\n" x; seen_list) 
    else x :: seen_list 
in 
List.fold_left uniq [] check_list 

uniq функция отображает список целых чисел в список целых чисел без повторений, регистрируя запись он пропускает.

Этот код, очевидно, предназначен для изучения материала, я думаю, тем не менее вы должны знать, что он скорее всего реализует Shlemiel the painter's algorithm.

Смежные вопросы