Есть немало возможных улучшений и ошибок в коде, и я их все перечислить в следующем:
No. 1
Если вы пишете код в файл и попытаться скомпилировать/запустить файл, то вам не нужно ;;
в конце концов, для каждой функции.
No. 2
let define_tuple a b = (a, b);;
Вам не нужно определить такую функцию, вместо этого, вы можете напрямую использовать (a, b)
.
No. 3
let zip (a, b) =
if List.length (fst (a, b)) != List.length (fst (a, b)) then
printf_string "lengths of 2 lists need to be equal"
else
let rec create_tuples (a, b) =
if List.length (List.tl (fst (a, b))) = 0 && List.length (List.tl (snd (a, b))) != 0
then
[]
else
List.append define_tuple (List.hd (fst (a, b))) (List.hd (snd (a, b))) create_tuples (List.tl (fst (a, b)), List.tl (snd (a, b)));;
3,1
для вашего первого if ... else ...
, это не правильно, как if
ветви возвращается unit
и else
ветви возвращается list
.
В OCaml, if
и else
или любая ветка соответствия шаблону должна возвращать тот же тип.
3,2
Из 3.1, я предлагаю вам написать исключение для non-equal lengths
случая. Таким образом, вся функция по-прежнему возвращает список, а код более читабельен, и пользователи вашей функции также могут получить возможность «поймать» ваш случай исключения.
3,3
для функции create_tuples
,
let rec create_tuples (a, b) =
if List.length (List.tl (fst (a, b))) = 0 && List.length (List.tl (snd (a, b))) != 0
then
[]
else
List.append define_tuple (List.hd (fst (a, b))) (List.hd (snd (a, b))) create_tuples (List.tl (fst (a, b)), List.tl (snd (a, b)));;
3.3.1
List.length (List.tl (fst (a, b))) = 0
Вам не нужно использовать fst (a,b)
, вместо этого, просто a
достаточно, потому что а уже известно.
Это то же самое для вашего использования snd
.
В принципе вам не нужны fst
и snd
на всем протяжении вашего кода.
3.3.1.1
Вы должны проверить, является ли a
и b
«ы длины равны 0 или нет, не tl
из них.
3.3.2
Вам также не нужно (a,b)
кортеж в качестве параметров для create_tuples
, вместо этого, вы можете использовать create_tuples a b
. Это лучше, потому что вашему коду не нужно создавать кортеж для пары параметров.
3.3.3
List.append define_tuple (List.hd (fst (a, b))) (List.hd (snd (a, b))) create_tuples (List.tl (fst (a, b)), List.tl (snd (a, b)))
Прежде всего, List.append
является добавление одного списка в другой список. В вашем случае вы добавляете элемент в список, поэтому вы должны использовать ::
.
Чтобы включить приложение функции, вы должны использовать ()
, если хотите, чтобы значение приложения функции использовалось.
например, вы должны сделать (define_tuple (List.hd (fst (a, b))) (List.hd (snd (a, b)))):: (create_tuples (List.tl (fst (a, b)), List.tl (snd (a, b))))
.
Если учесть предыдущие пункты вместе, вы можете сделать
(List.hd a, List.hd b)::(create_tuples (List.tl a) (List.tl b))
3,4
Вы определили функцию create_tuples
, но вы действительно использовать его в коде? Нет.
Таким образом, в конце концов, вы должны сделать
in create_tuples a b
No. 4
Вы должны использовать <>
проверить неравенство.
Полный утонченный/исправленный код
exception Non_equal_list_length
let zip a b =
if List.length a <> List.length b then raise Non_equal_list_length
else
let rec create_tuples a b =
if List.length a = 0 && List.length b = 0 then []
else (List.hd a, List.hd b)::(create_tuples (List.tl a) (List.tl b))
in
create_tuples a b
Некоторые другие улучшения:
- Вы можете использовать шаблон соответствия непосредственно в списках
- Вы всегда должны принимать хвост -рекурсивная оценка
Окончательный улучшенный код:
exception Non_equal_list_length
let zip a b =
let rec zipping acc = function
| [], [] -> List.rev acc
| hd1::tl1, hd2::tl2 -> zipping ((hd1,hd2)::acc) (tl1,tl2)
| _ -> raise Non_equal_list_length
in
zipping [] (a,b)
Вам действительно нужно научиться отступ своего кода или использовать редактор, который сделает это за вас. –
В настоящее время я использую Typerex, который находится здесь: http://www.typerex.org/ –
@ TrungBún вы должны использовать emacs + Tuareg, намного лучше –