Functional Programming – Getters and Setters in Functional Languages

functional programminghaskellscala

One of the tenets of Functional Programming is the use of Pure Functions. A Pure function is one that is side-effect free and referentially transparent.

Getters are not referentially transparent – if a Setter is called between calls to the Getter, the Getter's return value changes even though its parameters have not (typically no parameters)

Setters produce side-effects – Calling a Setter typically manipulates a value that is not its return value (in fact, traditionally a setter returns nothing)

I know in Scala we just kind accept the fact we are meshing together two paradigms (functional and object oriented) and use getters/setters as we would in a language like Java.

In a language like Haskell (which I'm not fluent with, but I'm told holds truer to a "Pure" functional language) I'm just curious, how you would model properties on objects such that Getters are referentially transparent and Setters are side-effect free?

Would the solution be to pass back a copy of the object the setter was invoked on as the setter's return value, and this copy contains the change to the property value?

Best Answer

Exactly. See case class method copy, or the general concept of lenses.

In particular, if state needs changing, you'd use a State monad. Changes to that state monad can be made through lenses, which makes extracting information from "state" and changing it easy.

See also this question about the general problem that comes from a deep structure like "state" and making changes to it. The answers have good links on both lenses and zippers if you want to get deeper into that.