Ответ 1
Вы можете делать больше вещей в монаде IO
, чем в монаде ST
. Последний предоставляет изменчивые ссылки, первый предоставляет изменяемые ссылки, исключение catch, потоки и, конечно, IO.
Обычно хорошая практика Haskell использует "самый слабый" или "более ограниченный" инструмент, который может решить вашу проблему, потому что "более слабые" инструменты, как правило, легче понять и проанализировать (в другом месте этот принцип возникает в Haskell находится в значении Applicative
по сравнению с Monad
).
Итак, если вам нужны только изменяемые ссылки, используйте ST
. Будущие разработчики смогут больше рассказать о том, что делает ваша функция (и не делает), просто глядя на тип.
Пример ситуации, в которой вы вынуждены использовать IORef
(или их двоюродных братьев MVar
s), - это когда нужно разделить изменяемую ссылку между двумя различными потоками выполнения.
Также имейте в виду, что вы можете избежать ST
(это означает, что вы можете запускать вычисления ST
внутри чистых функций), но вы не можете избежать IO
.