Допустим, вы хотите написать некоторую функцию с состоянием в Haskell. Вы должны использовать стиль monadi c следующим образом: (используя любую монаду состояний)
f :: x -> k -> (ST s) r
Таким образом, это означает, что, по сути, функция принимает некоторый ввод x
и k
, может использовать и / или измените мир, чтобы вычислить возвращаемое значение r
.
Предположим, x
является структурой с состоянием, которая может быть изменена с помощью f
. Предположим, k
- это просто простой тип ключа, используемый, например, для доступа к чему-либо в x
. Самому k
будет назначен простой тип номера позже, но нам не нужно сейчас определять его тип.
Так что, по сути, я знаю, что x
изменчива, а k
неизменна. Проблема только в том, чтобы посмотреть на сигнатуру f
, мы не можем этого сказать, поэтому, если f
встречается в теле более сложного монадического c кода, мы не можем очень хорошо рассуждать об этих переменных.
Пример:
g :: x -> k -> (ST s) r
g a i = do
...
f a i -- I don't know if i :: k depends on state
... --- I don't know if i was changed by f
Я имею в виду, что если мне дали переменную i
неизвестного типа k
, я не знаю, зависит ли она от s
и может ли на его значение повлиять вызов f
. Эта проблема, конечно же, не существует при написании чистых функций, поскольку все является неизменным.
Существует ли способ удобного аннотирования и, что более важно, статического обеспечения того, что k
останется неизменным в монаде ST при вызове f
?