Подтвердить что ты не робот

Как работает ArrowLoop? Кроме того, mfix?

Теперь я довольно комфортно отношусь к остальной части техники стрел, но я не понимаю, как работает цикл. Мне кажется волшебным, и это плохо для моего понимания. У меня также есть проблемы с пониманием mfix. Когда я смотрю кусок кода, который использует rec в блоке proc или do, я запутываюсь. С обычным монадическим или стрелочным кодом я могу выполнить вычисления и сохранить оперативную картину того, что происходит в моей голове. Когда я доберусь до rec, я не знаю, какую картину держать! Я застреваю, и я не могу рассуждать о таком коде.

Пример, который я пытаюсь сделать, это

Изменить. Благодаря ответу Pigworker, я начал думать о реквизите и, например, о выполнении требований. Принимая пример counter, первая строка блока rec требует значения, называемого output. Я предполагаю, что это оперативно, создавая ящик, обозначая его output и запрашивая блок rec, чтобы заполнить это поле. Чтобы заполнить это поле, мы передаем значение returnA, но это значение требует другого значения, называемого next. Чтобы использовать это значение, оно должно быть потребовано из другой строки в блоке rec, но не имеет значения, где в блоке rec требуется, на данный момент.

Итак, переходим к следующей строке, и мы находим поле с надписью next, и мы требуем, чтобы другое вычисление заполнило его. Теперь это вычисление требует нашей первой коробки! Поэтому мы даем ему поле, но оно не имеет ценности внутри него, поэтому, если это вычисление требует содержимого output, мы попадаем в бесконечный цикл. К счастью, задержка занимает окно, но дает значение, не заглядывая в окно. Это заполняет next, что позволяет нам заполнить output. Теперь, когда output заполняется, когда следующий вход этой схемы обрабатывается, предыдущее поле output будет иметь свое значение, готовое к требованию, чтобы создать следующий next, и, таким образом, следующий output.

Как это звучит?

4b9b3361

Ответ 1

В этом коде они представляют собой стрелку delay 0 в блоке rec. Чтобы увидеть, как это работает, это помогает думать о значениях, изменяющихся с течением времени, как нарезанных на кусочки. Я думаю о срезах как & lsquo; days & rsquo;. Блок rec объясняет, как работают вычисления каждый день. Он организован по значению, а не по каузальному порядку, но мы все равно можем отслеживать причинность, если будем осторожны. Решаем, мы должны убедиться (без какой-либо помощи от типов), что каждый день работа опирается на прошлое, но не на будущее. Однодневный delay 0 покупает нам время в этом отношении: он меняет свой входной сигнал на следующий день, заботясь о первом дне, задавая значение 0. Входной сигнал задержки - "завтра" next & rsquo;.

rec     output <- returnA -< if reset then 0 else next
        next <- delay 0 -< output+1

Итак, глядя на стрелки и их выходы, мы доставляем сегодня output, а завтра next. Рассматривая данные, мы полагаемся на сегодняшние значения reset и next. Ясно, что мы можем доставлять эти результаты с этих ресурсов без временных затрат. output - это сегодня next номер, если мы reset равны 0; завтра число next является преемником сегодняшнего дня output. Сегодня значение next имеет значение со вчерашнего дня, если не было вчера, и в этом случае это 0.

На более низком уровне вся эта установка работает из-за ленивости Haskell. Haskell вычисляет стратегию, основанную на спросе, поэтому, если есть последовательный порядок задач, которые уважают причинность, Haskell найдет это. Здесь delay устанавливает такой порядок.

Помните, что система типа Haskell дает вам очень мало помощи в обеспечении того, чтобы такой порядок существовал. Вы можете использовать петли для полной бессмыслицы! Таким образом, ваш вопрос далек от тривиального. Каждый раз, когда вы читаете или пишете такую ​​программу, вам нужно подумать и как это может работать? & Rsquo;. Вам необходимо проверить, что delay (или аналогичный) используется надлежащим образом, чтобы гарантировать, что информация требуется только тогда, когда она может быть вычислена. Обратите внимание, что конструкторы, особенно (:), могут также действовать как задержки. Необязательно вычислять хвост списка, по-видимому, учитывая весь список (но осторожно только для проверки головы). В отличие от императивного программирования, ленивый функциональный стиль позволяет организовать код вокруг концепций, отличных от последовательности событий, но это свобода, которая требует более тонкого осознания времени.