Единого правильного ответа на вопрос не существует, и наилучший подход будет зависеть от множества других ограничений и требований, которые у вас есть. Кроме того, это зависит от того, спрашиваете ли вы конкретно о F # или о функциональном программировании в целом. Я думаю, что есть три основных момента:
Упрощение. Использование модуля, представляющего gain
в качестве глобального значения, который имеет некоторый код инициализации для чтения конфигурации, кажется хорошим значением по умолчаниюподход в F #. Если это изменяется очень редко (скажем, до того, как вы запустите все вычисления), тогда мутация не вызовет никаких проблем. Вам просто нужно быть осторожным, чтобы избежать изменения значений, пока некоторые вычисления еще выполняются. Я думаю, что большинство программистов на F # склонны относиться к этому довольно прагматично, и это кажется самым легким для начала.
Модульное тестирование. Если вы хотите выполнить юнит-тестирование вашей multiplyByGain
функции с другим gain
в качестве аргумента, то вам понадобится какой-то способ передачи различных значений gain
к функции из ваших юнит-тестов. В этом случае хорошо иметь его в качестве дополнительного параметра и использовать каррирование, потому что вы можете просто вызывать его с другими значениями gain
из своих тестов.
Функциональное программирование. Некоторые функцииязыковые сообщества (особенно Haskell и, иногда, Scala) более строгие в отношении государства. Чисто функциональным способом сохранения состояния было бы использование монад (либо монады читателя, либо некоторой свободной структуры монад). Это делает ваш код намного более сложным (как концептуально, так и с точки зрения дополнительных синтаксических издержек), но это чисто функциональное решение, которое устраняет состояние. В F # такой подход еще более громоздок, поэтому он не очень распространен.