Если вы идентифицируете свои «изменяемые» переменные с помощью кортежа, вы можете определить операции преобразования для него и «связать» его вместе:
vars x y = (x,y)
setX (x,y) x' = (x', y)
setY (x,y) y' = (x, y')
appX (x,y) f = (f x, y)
appY (x,y) f = (x, f y)
app2X (x, y) f = (f x y, y)
app2Y (x, y) f = (x, f x y)
set...
устанавливает значение, app...
применяетФункция app2...
применяет функцию к обоим значениям и сохраняет ее в x или y.Затем вы можете сделать что-то вроде:
(vars 3 5) `setX` 14 `appY` (2*)
-- result: (14,10)
Ваш пример станет:
(vars 1 2) `app2X` (*) `app2Y` (+)
-- result: (2,4)
Конечно, это немного расширяет определение «изменяемый», но это решение уже на полпутив State
или Writer
монаду.