
Мы ковыряли поиск пути через A*
на протяжении двух глав и при этом были сосредоточены на синтаксических изысках F#. В этой главе мы отдохнём от синтаксиса и посмотрим на то, как этот алгоритм мог бы развиваться в более функциональном стиле.
User
Мы ковыряли поиск пути через A*
на протяжении двух глав и при этом были сосредоточены на синтаксических изысках F#. В этой главе мы отдохнём от синтаксиса и посмотрим на то, как этот алгоритм мог бы развиваться в более функциональном стиле.
В прошлой главе мы перенесли A*
на F#, после чего в образовательных целях занялись выдёргиванием его «кишок» наружу. Тогда процесс «потрошения» не был завершён до конца, но сегодня мы его добьём. Что касается метагейма, то мы продолжим путь от функции к конструктору и даже успеем слегка залезть на «ту сторону».
Концепция этого цикла начиналась с простого переноса тайловых миров на F#. Однако в процессе его описания я основательно растёкся по древу, за счёт чего у нас образовался большой подготовительный этап из пяти глав про языковые фичи и прочую «фундаменталочку». Думаю, что с подготовкой закончено, поэтому сегодня мы обратимся непосредственно к тайловым мирам.
Но начнём мы практически с конца — с адаптации поиска пути. Это несложная задачка, но в процессе её решения мы успеем закрепить пройденный материал и по инерции заскочить в новый.
Мы закончили обсуждать тело функции, и теперь пришло время вывода данных. Простые сценарии мы сразу отбросим, так как по ним уже хорошо прошлись, когда изучали выражения. Мы начнём с косяков выполнения, под которыми я подразумеваю не баги, а непреодолимые препятствия с различной степенью неожиданности. Это может прозвучать странно, так как аварийный выход не подпадает под определения output
, codomain
и т. д. Я с этим согласен и пересматривать эти термины не собираюсь. Однако меня интересует не только легитимная часть, но и вообще всё, что выходит из функции. Вплоть до того, что в следующих главах я начну включать в это аморфное понятие сайд-эффекты, фоновые процессы и много чего другого.
Я начал с ошибок, потому что Godot эту тему фактически проигнорировал, и вряд ли за ненадобностью, так как несколько раз мне уже было очень больно. У меня всё ещё не дошли руки покопаться в GDScript, так что я понятия не имею, вызван ли этот пробел ограничениями языка или архитектурным решением, но в любом случае нам его надо закрывать.
C# и ФП пропагандируют разные подходы к ошибкам. F#, будучи на перепутье, испытывает влияние обоих. Можно много говорить про плюсы взаимного обогащения культур, но судя по публичным баталиям, это не совсем наш случай. Вместо синтеза я куда чаще наблюдаю эмоциональные взрывы в среде представителей то одного, то другого лагеря. Я не буду ввязываться в эту борьбу (в этот раз) и сосредоточусь на решении более насущной задачи. Мне нужно доработать интероп так, чтобы он соблюдал привычную систему распределения ответственности. Так что сегодня только рутина, без красивых ходов и эффектных бросков.
В прошлых частях мы подключились к Godot, обсудили адаптацию к API и разобрались с устройством тела функции. Дальше в планах было перейти к входным и выходным данным, от них к общей архитектуре и далее снова к особенностям API. Если бы я отстрелялся быстрее, то так бы и было, но я возился слишком долго (об этом чуть ниже), из-за чего до моей телеги успел доползти читатель с типовым набором набивших оскомину вопросов. Допускаю, что я собрал всю коллекцию практикующих читателей, но мне хочется верить, что где-то прячется «молчаливое большинство» с аналогичными проблемами. Поэтому я решил передвинуть некоторые рассуждения из конца цикла в середину.
Это задержит кульминацию, но не критично, так как финальные части цикла я планировал запостить без длительных пауз. Поэтому эта глава пролежит в ожидании до тех пор, пока не будет готов черновик всего цикла. Если этот текст появился на Хабре, то остальные главы уже на подходе.
Этой статьёй я хочу внести некоторые правки в алгоритм развёртывания, который я описывал год назад вот здесь. Статья тогда получилась объёмная, и я искал способы её сократить, в результате чего опрометчиво пренебрёг несколькими сценариями, которые пригодились мне в дальнейшей разработке. Они образовали техдолг, который мне необходимо закрыть ввиду грядущего продолжения.