Как отлаживать переменные / рекурсивные типы данных в Haskell - PullRequest
0 голосов
/ 29 ноября 2018

https://www.inf.ed.ac.uk/teaching/courses/inf1/fp/exams/exam-2016-paper1-answers.pdf

-- 3b
trace :: Command -> State -> [State]
trace Nil s = [s]
trace (com :#: mov) s = t ++ [state mov (last t)]
where t = trace com s

У меня проблемы с пониманием раздела 3b.Я пытаюсь отладить переменные одну за другой, но всегда заканчиваю нарушением определенных типов данных.Код смущает меня, и я хочу посмотреть, что содержат переменные.Как я могу сделать это с помощью Debug.Trace?

https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base-4.12.0.0/Debug-Trace.html

Спасибо.

1 Ответ

0 голосов
/ 29 ноября 2018

Похоже, в разделе 3b преподается «Как работает рекурсия» Эти слайды охватывают только обычные списки Haskell.То, что у вас есть с :#:, является противоположностью, иногда называемой списком snoc.Тогда разумным дизайном для trace будет также вывод списка snoc.Но это не так (вероятно, потому что лектор думает, что, мучая начинающих, таких как они, они чему-то научатся).Понимание списков на Haskell работает только для списков, а не snoc.(Тогда половина содержимого этих слайдов бесполезна для этого упражнения.) Таким образом, 3b обучает вас структурной инверсии через рекурсию (что является полезной половиной слайдов).

нарушение определенных типов данных

Переменная t в коде, который вы даете, является локальной для функции trace, поэтому доступ к ней кажется затруднительным.Но его определение

t = trace com s

не является:

  • Мы знаем trace :: Command -> State -> [State]
  • Мы можем видеть в уравнении для t, что trace естьприменяется к двум аргументам.
  • Таким образом, тип t должен быть типом результата trace, то есть [State].

Вы не уверены, чтотип аргументов для trace в уравнении для t?В частности, com распаковывается из аргумента Command в trace на верхнем уровне.

  • Тогда нам нужно понять тип для :#:.У нас есть вопрос 3

    data Command =
         Nil
       | Command :#: Move
    
  • Это делает (:#:) инфиксным оператором (именно поэтому я поставил его в скобках).

  • Затем мы можем спросить GHCi о его типе, чтобы удостовериться.
  • Используйте команду :type, обязательно поставьте парены.
  • Для контраста, также попросите :type из обычного списка Haskell cons tructor (:) - см. инверсию влево-вправо?

  • Термин слева от (:#:) имеет тип Command.

  • Тогда переменная com в уравнении для t должна иметь тип Command;и это соответствует тому, что ожидает вызов trace.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...