2016-03-30 4 views
2

Каково точное определение чистой функции в Scala? Чистая функция имеет определение, на wiki https://en.wikipedia.org/wiki/Pure_function. Я думаю, что это определение предназначено для чистого функционального языка программирования.Чистая функция в Scala в контексте методов класса и замыканий

Однако, я думаю, что это осложняется в контексте метода класса и закрытия.

class Ave(val a: Int, val b: Int) { 
    def ave = (a+b)/2 
} 

Является ли аве чистой функцией? Я думаю, что это так, потому что у него нет побочного эффекта, и это зависит только от непреложного состояния класса. Но это фактически нарушает определение чистой функции в wiki, которая говорит, что чистая функция обычно не должна обращаться к нелокальной переменной.

Похожий вопрос о закрытии:

def fcn(a:Int, b: Int): Unit = { 
    def ave = (a+b)/2 
} 

Для меня, как пр чистые функции, и эквивалентно «VAL» (единый принцип доступа).

Но как строго оправдывать? Более того, если поля a и b являются изменяемыми, ave больше не является чисто функциональным.

class Ave2(var a: Int, var b: Int) { 
    def ave = (a+b)/2 // Not pure functional 
} 

Другого определение чистой функция происходит из «функционального программирования в Scala» книга:

Выражение е референциально прозрачные, если для всех программ р всех вхождений е в р могут быть заменяется результатом оценки e, не затрагивая значения p. Функция F является чистым, если выражения Р (х) референциально прозрачный для всех референциальна прозрачных х

Тогда возникает вопрос, для класса, является изменяемым состоянием в классе референциально прозрачным (вар а, var b в моем примере)? (Если это так, то метод ave в Ave2 становится чистой функцией, что является противоречием)

Каково точное определение чистой функции в Scala?

ответ

4

Короткий ответ:
Затворы не помешают чистоты, пока закрытые поверх переменные неизменны.

Длинный ответ:
В действительно функциональном языке программирования нелокального переменных никогда не изменится, так что наличие замыкания не влияет на чистоту. Функции Haskell чисты, и все же Haskell использует замыкания без проблем. Пока ваша функция подчиняется правилу отсутствия побочных эффектов и имеет один и тот же результат для одного и того же набора параметров каждый раз, когда он вызывается (другими словами, не имея изменяемого состояния), вы получаете ссылочную прозрачность и, следовательно, чистоту. Если вы задумываетесь над теоретическим взглядом на вещи, я полностью понимаю, что беспокоюсь о закрытии, поскольку чистые функции должны зависеть только от их аргументов и их аргументов (не обязательно всех из них). Но с практической точки зрения закрытие неизменяемых переменных не считается нарушением чистоты.

Обратите внимание, что локальное изменчивое состояние не обязательно подвергает опасности чистоту.Это скользкий ландшафт, но Мартин Одерски сказал один раз (я могу выкопать точный источник, если я действительно должен, это была либо лекция на одном из курсов Курсеры, либо книга «Программирование в Скале»), что варны в порядке до тех пор, пока вы держите их невидимыми для внешнего мира. Так что это глупая функция:

def addOne(i: Int) = { 
    var s = i 
    s = s + 1 
    s 
} 

можно считать чистой, даже если он использует изменяемое состояние (переменная s), потому что изменяемое состояние не подвергаются «внешнему миру» и не ставит ссылочную прозрачность метода addOne в опасности.

+0

Спасибо за ответ! Я думаю, что это говорит о закрытии, как насчет метода, типа класса Ave выше? Действует ли одно и то же правило? Существует ли у Haskell понятие класса и метода? – szli

+0

Да, то же самое относится. Почему нет? В этом случае 'ave' - это метод, а не функция, поэтому вы не можете ожидать, что он будет иметь одинаковые результаты при вызове на разные объекты. Но вызовы на одном объекте всегда будут давать одинаковый результат. Что касается Haskell, нет, там нет классических концепций ООП. Существуют классы типов, но это что-то другое (кстати, вы можете также моделировать классы типов в Scala с использованием параметризованных признаков и неявных реализаций их для разных типов, но это не по теме). – slouc