Ответ 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
(или аналогичный) используется надлежащим образом, чтобы гарантировать, что информация требуется только тогда, когда она может быть вычислена. Обратите внимание, что конструкторы, особенно (:)
, могут также действовать как задержки. Необязательно вычислять хвост списка, по-видимому, учитывая весь список (но осторожно только для проверки головы). В отличие от императивного программирования, ленивый функциональный стиль позволяет организовать код вокруг концепций, отличных от последовательности событий, но это свобода, которая требует более тонкого осознания времени.