#haskell
#haskell
Вопрос:
Задача (домашнее задание): учитывая список целых чисел, верните список кортежей, где каждый кортеж в списке имеет вид (int_val, val_freq). Встроенные функции не допускаются. Разрешенные операторы: :, .
Попытка 1:
simplify :: [ Int ] -> [( Int , Int )]
simplify [] = []
simplify ((x:xs) [(a, b)]) =
if x == a then (simplify xs [(x, b 1)])
else (simplify xs [(x, 0)])
Попытка 2:
naive_enumerate :: [ Int ] -> [( Int , Int )]
naive_enumerate [] = []
naive_enumerate x:xs =
if x == y then [(y, 1)] naive_enumerate xs
enumerate_tuple_list :: [( Int , Int )] -> [( Int , Int )]
enumerate_tuple_list [] = []
enumerate_tuple_list ((a, b):(c, d):rest) =
if (a == c) then (a, b d):(enumerate_tuple_list rest)
else (a, b d):(enumerate_tuple_list rest)
simplify :: [ Int ] -> [( Int , Int )]
simplify some_list = enumerate_tuple_list (naive_enumerate some_list)
Ожидается: например, для ввода [1, 2, 2, 3] вывод [(1,1), (2, 2), (3,1)].
Фактический результат: при попытке 1 я получил ошибку при
упростить ((x: xs) [(a, b)]) =
При попытке 2 моя ошибка синтаксического анализа возникает при
enumerate_tuple_list :: [(Int , Int )] -> [(Int , Int )]
Вопросы:
- Каков правильный синтаксис для перебора кортежей в списке?
- Можете ли вы объяснить, почему я получаю обе ошибки синтаксического анализатора?
- Почему Haskell запрещает код, подобный следующему:
наивное число x:xs = [(x, 1)] наивное число xs
Обновление: попытка 3: благодаря предложениям до сих пор, теперь у меня есть
simplify :: [ Int ] -> [( Int , Int )]
simplify [] = []
simplify (x:xs) = let recursive_result = simplify xs
update n ((a, b):pairs) =
if n == a then ((a, b 1):pairs)
else ((n, 1):pairs)
in update x recursive_result
Теперь код компилируется, но я получаю следующую ошибку:
Исключение: … Неполные шаблоны в обновлении функции
Отсюда дополнительные вопросы:
- Какие регистры я пропускаю?
- Возможно ли перехватить ошибку во время компиляции (параметры debug / verbose не помогают)?
Комментарии:
1. Полный ответ займет больше времени, чем у меня на данный момент (но я уверен, что кто-то другой скоро его предоставит). Но ваша ошибка синтаксического анализа при попытке 2 связана с тем, что у вас есть
if ... then
оператор с noelse
Ответ №1:
В настоящее время вы пытаетесь выполнить итерацию по возвращаемому значению, как если бы оно было аргументом. Сначала вам нужно выполнить рекурсивный вызов, а затем обновить этот результат
simplify [] = []
simplify (x:xs) = let recursive_result = simplify xs
update n pairs = ...
in update x recursive_result
где ...
вы пытаетесь найти и заменить пару, которая уже содержит x
, или добавить новую пару.
Подсказка: встроенная lookup
функция поможет, если вы сможете убедить своего учителя разрешить вам ее использовать.
Ответ №2:
Прежде всего, спасибо всем респондентам. Я отвечу на все свои вопросы здесь и в конце ответа предоставлю (спойлер) пример решения.
- Каков правильный синтаксис для перебора кортежей в списке?
Списки не должны повторяться. Написать функцию для такой структуры данных,
имя_функции ((элемент1, элемент2, …, элементN):some_list) = результат
Моя ошибка заключалась в том, что я проигнорировал приоритет привязки конструктора создания списка: и приложения функции.
- Можете ли вы объяснить, почему я получаю обе ошибки синтаксического анализатора?
Уже ответил.
- Почему Haskell запрещает код, подобный следующему:
Объяснено Чепнером.
- Какие регистры я пропускаю?
Случай, когда существуют списки с 1 элементом.
- Возможно ли перехватить ошибку во время компиляции?
Возможно с помощью HTF.
ПРЕДУПРЕЖДЕНИЕ О СПОЙЛЕРЕ, И вот моя попытка 5:
simplify :: [ Int ] -> [( Int , Int )]
simplify [] = []
simplify (x:xs) = let recursive_result = simplify xs
update n [] = [(n, 1)]
update n ((a, b):pairs) =
if n == a then ((a, b 1):pairs)
else (a, b):(update n pairs)
in update x recursive_result