IO работает с кучей Хаскеля

Автор оригинала: Edward Z. Yang
  • Перевод
Начало серии Куча Хаскеля
В этой статье мы сосредоточимся на вас. Вы всё крутитесь около кучи Хаскеля и норовите открыть подарок. В конце концов, подарки сами по себе не открываются.


Кто-то должен открыть первый подарок.

Если куча Хаскеля не взаимодействует с внешним миром, то открывать подарки не нужно. Следовательно, делать это будут только IO функции. Не всегда очевидно, какой конкретно подарок откроет функция. Поэтому посмотрим на простейшую evaluate. Которая просит вас...

… просто открыть подарок.
Если вам досталось примитивное значение, то на этом всё. Но может достаться подарочный сертификат (конструктор):

Будете ли вы открывать по нему подарки? Несмотря на ваше горячее желание, ответ — нет. evaluate просит вас открыть только один подарок. А если от уже открыт, то вам вообще ничего не нужно делать.


Совет: Если вы хотите вычислить больше, создайте подарок с духом, который сделает работу за вас! Часто приводят такой пример ленивых IO вычислений evaluate (length xs). Но сильно не беспокойтесь, если вы этого ещё не понимаете: я ещё не рассказал, как создавать подарки!

Хотя мы открываем только один подарок, много чего может случиться. Я писал об этом в прошлой статье. Может выполниться какой-нибудь IO (побочный эффект)...

Побочные эффекты позволяют подглядеть за порядком вычислений. Ведь если запустить программу обычным образом, то мы не увидим, когда подарок открывается. Но если попросить духа закричать, когда его потревожат, то мы об этом узнаем. В действительности, это в точности то, чем занимается Debug.Trace!

Есть и другие способы узнать, как продвигаются вычисления. Подарок может взорваться, если он заминирован. Мины ещё называются “bottom” (логическое противоречие).


Возможно, взрыв был вызван undefined или error "Foobar".

Бум.

Закончим практическим советом. Как мы видели, можно быть уверенным, что подарок открыт, только в том случае, если явно попросить об этом в IO. Иначе, дух может вас обмануть. Ведь вы не можете непосредственно видеть кучу Хаскеля, поэтому нет прямого способа узнать открыт подарок или нет.


Если вы не уверены, что thunk вычисляется, то прикрепите к нему трассировку. И если за вашей спиной духи ленятся, то трассировка не сработает.

Но чаще вы всё же увидите трассировку, хотя и позже, чем ожидаете (духи ленивы, но когда-нибудь сделают свою работу). Бывает полезно досрочно выйти из программы или распечатать пройденные этапы вычислений.

В прошлый раз: Вычисление в куче Хаскеля
В следующий раз: Реализация кучи Хаскеля на Питоне, v1

Замечание. В противоречие тому, что я говорил ранее, теоретически ничто не мешает выполнять thunk'и в куче в произвольном порядке: это называется спекулятивное вычисление. К тому же, IO действия сами могут быть thunk'ами, что соответствует передаче значения (IO a) без его реальной “прогонки”. Но так как я здесь не ради монад, то просто не буду обращать внимания на подарки с IO действиями — там всё работает также, только добавляется ещё один уровень косвенности. И последнее, бесконечные циклы также считаются bottom, но картинка, на которой открытие подарка длится до скончания веков не так захватывает, как взрывающийся подарок.

Комментарии 3

    +1
    Психоделическое введение в хаскель продолжается :).
      +6
      Опытный хаскелист сумеет создать достаточно сложную и непонятную абстракцию для рассказа даже о такой достаточно простой вещи, как ленивые вычисления.

      А хороший хаскелист удержится в рамках этой абстракции до самого конца рассказа.

      С нетерпением жду следующей части и, скрестив пальцы, загадываю, чтобы там было про duck typing на Python-е в рамках метафоры подарков.
        +4
        Как начавший изучать Хаскель, скажу, что Real World Haskell лучше идёт, хотя в это статье проскакивают очень интересные факты.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое