#functional-programming #ocaml #quicksort
#функциональное программирование #ocaml #быстрая сортировка
Вопрос:
Я пытаюсь реализовать алгоритм быстрой сортировки в OCaml, и я думал, что он у меня есть, но он не компилируется, и я просто не могу понять, что с ним не так. Вот мой код:
let rec quicksort list =
match list with
[] -> []
|h::t -> append((quicksort (filter (largerthan h)
t))(quicksort(filter (smallerthan h) t)));;
let largerthan x y =
x<y;;
let smallerthan x y =
x>y;;
let rec append x y =
match x with
[] -> y
| h::t -> h:: append t y;;
let rec filter f list =
match list with
[] -> []
|h::t -> (if f h = true then h:: filter f t else filter f t);;
Теперь, когда я пытаюсь использовать это в OCaml, появляется сообщение «Ошибка: это выражение имеет тип ‘a -> ‘b
но ожидалось выражение типа «a», указывающее на последнюю строку моей функции быстрой сортировки.
Кто-нибудь знает, что происходит не так??
Большое спасибо!
Линус
Редактировать: Хорошо, я избавился от исходной ошибки (спасибо ADEpt :)). Однако теперь функция просто выводит пустой список независимо от входных данных… Кто-нибудь знает, что там происходит??
Комментарии:
1. вам не нужно для большего, просто используйте ( < ) (с paren). То же самое верно для меньшего размера, чем (с использованием ( > )).
2. Обратите также внимание, что на самом деле это не будет быстрая сортировка, потому что добавление происходит медленно (первая часть списка будет собрана дважды …)
3. Обратите также внимание, что
append
иfilter
уже доступны в базовой библиотеке, как(@)
(инфиксный оператор,xs @ yx
) иList.filter
соответственно.
Ответ №1:
У вас есть дополнительные скобки в вызове «применить». Вместо:
append((быстрая сортировка (фильтр (больше, чем h) t))(быстрая сортировка (фильтр (меньше, чем h) t))
Напишите это:
добавить (быстрая сортировка (фильтр (больше, чем h) t)) (быстрая сортировка (фильтр (меньший, чем h) t))
Комментарии:
1. или даже лучше это:
let left = quicksort (filter (largerthan h) t) in let right = quicksort (filter (smallerthan h) t) in append left right
(с правильными окончаниями строк, которые я не уверен, что смогу вставить в комментарий; это выглядит намного более читабельным)2. Спасибо! Это устранило ошибку. Однако сейчас я просто получаю пустой список в качестве выходных данных… Кто-нибудь знает, что там происходит не так? 🙂
3. Вам нужно превратить ‘largetthan’ и ‘smallerthan’ в ‘largerthan’ и ‘smallerorequalthen’ 🙂 В противном случае нет подсписка, содержащего ‘h’
Ответ №2:
Что касается вашего «второго» вопроса: вы забыли добавить h в отсортированный список….
Ответ №3:
OCaml компилирует вашу программу в том порядке, в котором вы ее передаете. В этом вопросе все очень строго. если вы что-то используете, вам нужно указать это, прежде чем использовать. Если вы замените определение, впоследствии будет использоваться новое определение, но до этого старое.
Если брать ваш код сверху вниз, вот что получается:
let rec quicksort list =
match list with
[] -> []
|h::t -> append((quicksort (filter (largerthan h)
t))(quicksort(filter (smallerthan h) t)));;
На данный момент нет определения largerthan
, smallerthan
filter
or append
, поэтому компилятор не знает, что с этим делать.
Измените порядок вашего кода, и несколько проблем исчезнут.
Комментарии:
1. Также обратите внимание: попробуйте использовать методы из стандартной библиотеки или какую-нибудь хорошую замену стандартной библиотеки (например, батарейки), где это возможно.
filter
иappend
там уже присутствуют.2. Привет, спасибо за объяснение. Тем не менее, я только что разместил функции в этом порядке здесь, в моих исходных файлах порядок правильный :).
3. ОК. Всегда указывайте код, в котором проявляется проблема, чтобы не вводить в заблуждение других, когда предоставляемый вами код содержит дополнительные проблемы.