Закрытия не являются нарушением, потому что все привязки в Haskell неизменны. Что на самом деле означает замыкание, так это то, что лямбда со свободными переменными не обозначает одну уникальную функцию; он будет обозначать различные функции в зависимости от привязок, которые действуют для его свободных переменных при каждой оценке. E.g.:
makeClosure :: Num a => a -> a -> a
makeClosure x = \y -> x+y
Выражение makeClosure 5
оценивается как функция, отличная от makeClosure 6
; и что еще более важно, два вхождения makeClosure 5
в разных частях программы оцениваются для одной и той же функции , как и для makeClosure (2+3)
или аналогичной; то есть, у нас ссылочная прозрачность (замена выражений на их равные сохраняет смысл программы).
Вы, кажется, смущены значением слова "состояние" в упомянутой вами цитате. Состояние в этом контексте означает изменчивые данные; замыкания могут определенно «скрывать» данные, но в Haskell эти данные не являются изменяемыми, поэтому они не скрывают состояние. В противоположность этому, по моему опыту, Java-программисты часто говорят, что экземпляр класса «скрывает состояние» в тех случаях, когда данные не являются изменяемыми, например, присваиваются полю экземпляра private final
из конструктора; на самом деле они имеют в виду, что классы (и замыкания) инкапсулируют данные.