Функция Haskell в списке кортежей

#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 )]

Вопросы:

  1. Каков правильный синтаксис для перебора кортежей в списке?
  2. Можете ли вы объяснить, почему я получаю обе ошибки синтаксического анализатора?
  3. Почему 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
 

Теперь код компилируется, но я получаю следующую ошибку:

Исключение: … Неполные шаблоны в обновлении функции

Отсюда дополнительные вопросы:

  1. Какие регистры я пропускаю?
  2. Возможно ли перехватить ошибку во время компиляции (параметры debug / verbose не помогают)?

Комментарии:

1. Полный ответ займет больше времени, чем у меня на данный момент (но я уверен, что кто-то другой скоро его предоставит). Но ваша ошибка синтаксического анализа при попытке 2 связана с тем, что у вас есть if ... then оператор с no else

Ответ №1:

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

 simplify [] = []
simplify (x:xs) = let recursive_result = simplify xs
                      update n pairs = ...
                  in update x recursive_result
 

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

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

Ответ №2:

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

  1. Каков правильный синтаксис для перебора кортежей в списке?

Списки не должны повторяться. Написать функцию для такой структуры данных,

имя_функции ((элемент1, элемент2, …, элементN):some_list) = результат

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

  1. Можете ли вы объяснить, почему я получаю обе ошибки синтаксического анализатора?

Уже ответил.

  1. Почему Haskell запрещает код, подобный следующему:

Объяснено Чепнером.

  1. Какие регистры я пропускаю?

Случай, когда существуют списки с 1 элементом.

  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