Аккумуляторная фабрика в Хаскеле
Сейчас, в начале моего приключения с программированием, у меня возникли проблемы с пониманием основных понятий. Вот один, связанный с Haskell или, возможно, в целом функциональная парадигма.
Вот общая формулировка проблемы фабрики аккумуляторов, с http://rosettacode.org/wiki/Accumulator_factory
[Написать функцию, которая]
Принимает число n и возвращает функцию (давайте назовем ее g), которая принимает число i и возвращает n, увеличенное на накопление i при каждом вызове функции g(i).
Работает для любого числового типа - т.е. может принимать как целые числа, так и числа с плавающей запятой и возвращает функции, которые могут принимать значения как числа, так и числа с плавающей запятой. (Недостаточно просто преобразовать все входные данные в числа с плавающей точкой. Аккумулятор, который видел только целые числа, должен возвращать целые числа.) (Т.е., если язык не допускает числовой полиморфизм, вы должны использовать перегрузку или что-то в этом роде)
Создает функции, которые возвращают сумму каждого числа, когда-либо переданного им, а не только самого последнего. (Для этого требуется элемент состояния для хранения накопленного значения, что, в свою очередь, означает, что для этой задачи нельзя использовать чисто функциональные языки.)
Возвращает реальную функцию, означающую что-то, что вы можете использовать везде, где вы можете использовать функцию, которую вы определили обычным способом в тексте вашей программы. (Следуйте правилам вашего языка здесь.)
Не хранит накопленное значение или возвращенные функции таким образом, что они могут быть непреднамеренно изменены другим кодом. (Нет глобальных переменных или других подобных вещей.)
с, как я понимаю, ключевым моментом является: "[...] создание функции, которая [...] генерирует функции, которые возвращают сумму каждого числа, когда-либо переданного им, а не только самого последнего. (Это требует часть состояния для хранения накопленного значения, что, в свою очередь, означает, что чисто функциональные языки не могут использоваться для этой задачи.)"
Мы можем найти решение Haskell на том же веб-сайте, и оно, кажется, делает то, что говорится в приведенной выше цитате.
Здесь http://rosettacode.org/wiki/Category:Haskell сказано, что Haskell является чисто функциональным.
Каково же объяснение очевидного противоречия? Или, может быть, нет никакого противоречия, и мне просто не хватает понимания? Благодарю.
1 ответ
Решение Haskell на самом деле не совсем соответствует правилам испытания. В частности, это нарушает правило, согласно которому функция "возвращает реальную функцию, что означает то, что вы можете использовать везде, где вы можете использовать функцию, которую вы определили обычным способом в тексте вашей программы". Вместо того, чтобы возвращать реальную функцию, она возвращает ST
вычисление, которое производит функцию, которая сама производит больше ST
вычисления. В контексте ST
"State Thread", вы можете создавать и использовать изменяемые ссылки (STRef
), массивы и векторы. Однако это изменяемое состояние не может "просочиться" за пределы потока состояния, чтобы загрязнить чистый код.