Одно из самых больших свойств чисто функциональной программы, которая позволяет избежать изменяемые переменные и другие побочные эффекты, в том, что значение, которое выражение принимает значение зависит только от самого выражения. Это не зависит от того, какой порядок оценивается (слева направо, справа налево, строгий, ленивый), состояние операционной системы, время суток и т. Д.
В частности, это означает, что в чисто функциональный параметр, каждый вызов new C
будет возвращать полностью идентичный объект-счетчик. Это, как правило, хорошо, потому что это облегчает рассуждение о вашей программе, но это немного мешает тому, что вы пытаетесь сделать там. Чтобы объекты C были разными, вам нужно явно передавать свои значения счетчиков, что, если честно, просто подметает проблему под ковриком.
val c1 = new C(0)
val c2 = new C(1)
Если вы хотите иметь глобальный «счетчик» переменный как внутренний переменный класса вы, используя один из возможных способов ее реализации в чисто функциональном назначении были бы передать значение счетчика для каждой функции, которая нуждается в счетчик, и эти функции также возвращают обновленную версию счетчика. Для краткого примера:
def increment_counter(n: Int): Int = { n + 1)
def create_c(n: Int): (C, Int) = {
val c = new C(n)
val n' = increment_counter n
(c, n')
}
val n = 0
val (c1, n') = create_c(n)
val (c2, n'') = create_c(n')
val n' = increment_counter(n)
Вы можете структурировать это немного лучше с рисунком государства Монады (большинство введений в монады, вероятно, будут иметь это в качестве примера).
Однако очень возможно, что это будет сложнее, чем просто использовать изменяемую переменную для счетчика. Фактически, я обычно использую переменные переменные для этих «глобально увеличивающих счетчиков» на функциональных языках, которые позволяют мне это делать.
Функциональные или государственные Монады кажутся подходящими – naomik