Другой способ объяснить это так: никакая функция не может получить текущее время (поскольку оно постоянно меняется), но действие может получить текущее время.Скажем, getClockTime
- это константа (или нулевая функция, если хотите), которая представляет действие получения текущего времени.Это действие одинаково каждый раз, независимо от того, когда оно используется, поэтому оно является реальной константой.
Аналогично, скажем, print
- это функция, которая принимает некоторое представление времени и печатает егона консоль.Поскольку вызовы функций не могут иметь побочных эффектов на чистом функциональном языке, мы вместо этого представляем, что это функция, которая берет временную метку и возвращает действие печати ее на консоль.Опять же, это реальная функция, потому что если вы дадите ей одну и ту же временную метку, она будет возвращать одно и то же действие печати ее каждый раз.
Теперь, как вы можете напечатать текущее времяна консоль?Ну, вы должны объединить два действия.Так как мы можем это сделать?Мы не можем просто передать getClockTime
в print
, так как печать ожидает метку времени, а не действие.Но мы можем представить, что существует оператор >>=
, который объединяет два действия, одно из которых получает временную метку, а другое принимает одно в качестве аргумента и печатает его.Применение этого к ранее упомянутым действиям приводит к ... tadaaa ... новому действию, которое получает текущее время и печатает его.И это, кстати, именно так, как это делается в Haskell.
Prelude> System.Time.getClockTime >>= print
Fri Sep 2 01:13:23 東京 (標準時) 2011
Итак, концептуально, вы можете посмотреть на это следующим образом: чисто функциональная программа не выполняет никаких операций ввода-вывода, она определяет действие , которое затем выполняет система времени выполнения. действие всегда одинаково, но результат его выполнения зависит от обстоятельств, когда оно выполняется.
Я не знаю, было ли это более ясным, чем другие объяснения, но иногда это помогает мне думать об этом таким образом.