Прежде всего, поскольку вопрос каким-то образом связан со школьным проектом, я не думаю, что размещение моего кода уместно. К тому же, как я объясню позже, у меня есть только модифицированная версия рассматриваемого кода.
И я объясняюсь. Я должен реализовать версию алгоритма Дейкстры с использованием очереди приоритетов. Я думал, что простой функциональный способ сделать это - определить функцию dijkstra с входами очереди и целевого узла и вспомогательной функцией для постановки в очередь узлов, которые являются соседями для элемента списка, который только что был исключен из очереди. К сожалению, вспомогательная функция не проверила тип - Unresolved Flex Record.
Пока может показаться, что код важен, но позвольте мне добавить еще одну деталь. Поскольку граф был 4-каноническим (что означает, что каждый узел имеет ровно четыре соседа), я представил его как матрицу, используя арифметику модулей. Чтобы упростить свой алгоритм, я использовал этот факт, чтобы переписать его и использовать 4 дополнительные вспомогательные функции - по одной для каждого возможного хода - вместо четырех if внутри первой вспомогательной функции. Каждая из четырехходовых функций возвращает истину, если мы должны посетить этот узел (что означает, что стоимость, которая нам понадобится таким образом, меньше, чем текущая необходимая стоимость), и ложь, если нет. А первый помощник просто возвращает кортеж из четырех логических переменных. Наконец, я скопировал код постановки в очередь, который не работал при моей первой попытке, в тело кода Дейкстры, и внезапно он выполнил проверку типов.
Я понимаю, что это все еще может быть неясным, и, возможно, вы можете только догадываться о том, что происходило. Но я действительно очень озадачен. Я искал этот сайт и базу SML и обнаружил, что такого рода ошибка возникает в следующем случае:
f (x,y,z) = ...
где z не используется, поэтому средство проверки не может определить, что это такое. Я уверен, что в моей проблеме это не так, поскольку я просто копирую и вставляю код (не очень хороший метод, который я знаю, но хорошо). Отсюда я пришел к выводу, что проблема в том, что проверка типов не работает с вызовами функций. Я поискал снова и нашел объяснение алгоритма Хиндли Миллера. И из того, что я понял каждый раз, когда он встречается, функция будет считать, что это a-> b в качестве первого шага, а затем перейду к определению функции и завершит задачу. Итак, я вернулся к исходной точке и решил задать этот вопрос здесь, чтобы лучше понять вывод типов или намек на то, что происходит.
P.S. 1) Несмотря на то, что я изо всех сил пытался объяснить вопрос, он все еще неясен или слишком широк, дайте мне знать, и я удалю, без проблем. P.S. 2) Меньший и более простой вопрос: я прочитал, что №1 не рекомендуется брать 1-й элемент кортежа, и иногда он даже не проверяет тип, и вместо этого следует использовать сопоставление с образцом. Не могли бы вы это объяснить? P.S. 3) Кто-то может спросить, почему я задал этот вопрос, раз уж я решил проблему со второй попытки. Лично я не считаю решенным, а скрытым.
Заранее спасибо и извините за размер вопроса.
Ссылки:
ОБНОВЛЕНО: после дополнительных поисков я догадываюсь, что было не так. Я реализовал приоритетную очередь, не настроенную для моей проблемы, а более общую. Итак, вывод типа очереди с приоритетом имел место, когда я впервые поставил элемент в очередь. Но после постановки в очередь моего исходного узла и вызова dijkstra очередь снова станет пустой (мой dijsktra удалял из очереди первый элемент, проверяя, является ли он целевым узлом), и первый вызов вспомогательной функции, которая добавляет узлы, будет иметь пустую очередь как один своих аргументов. Возможно, пустая очередь не имеет типа, и это вызвало ошибку?