В чем разница между STRef и IORef и когда я использую каждый из них? Насколько я могу судить, они оба предназначены для изменчивого состояния, так что точка их обоих существует?Когда использовать STRef или IORef?
ответ
Вы можете сделать больше вещей в IO
монады, чем в ST
монады. Последний предоставляет изменчивые ссылки, первый предоставляет изменяемые ссылки, исключение catch, потоки и, конечно, IO.
Как правило, хорошая практика Haskell заключается в использовании доступного «слабого» или «более ограниченного» инструмента, который может решить вашу проблему, поскольку «более слабые» инструменты, как правило, легче понять и проанализировать (в другом месте этот принцип возникает в Haskell находится в разряде Applicative
против Monad
).
Итак, если вы только нужны изменяемые ссылки, используйте ST
. Будущие разработчики смогут больше рассказать о том, что делает ваша функция (и не делает), просто глядя на тип.
Пример ситуации, в которой вы вынуждены использовать IORef
s (или их кузены MVar
s), является необходимость обмена изменяемой ссылкой между двумя различными потоками выполнения.
Также имейте в виду, что вы можете избежать ST
(что означает, что вы можете запускать вычисления ST
внутри чистых функций), но вы не можете избежать IO
.
Каждый из них обеспечивает ту же функциональность, что и для разных монадов. Используйте IORef
, если вам нужен управляемый рефлекс в IO
и STRef
, если вам нужен он в ST s
.
EDIT: краткий пример:
import Control.Monad.ST
import Data.IORef
import Data.STRef
exampleSTRef :: ST s Int
exampleSTRef = do
counter <- newSTRef 0
modifySTRef counter (+ 1)
readSTRef counter
exampleIORef :: IO Int
exampleIORef = do
counter <- newIORef 0
modifyIORef counter (+ 1)
putStrLn "im in ur IO monad so i can do I/O"
readIORef counter
- 1. Составление IORef и STRef
- 2. Преобразование даты и времени в iEF
- 3. Когда использовать!() Или! = Когда, если не нулевой
- 4. Когда использовать (или не использовать) делегат
- 5. Синхронизация, когда использовать или не использовать?
- 6. Когда использовать tensorflow или api.ai
- 7. Когда использовать NaN или +/- Infinity?
- 8. , когда использовать ajax.load() или jquery.ajax()
- 9. Когда использовать (: метод) или (&: метод)
- 10. Когда использовать HANDLE_EINTR или HANDLE_EAGAIN?
- 11. объекты или затворы - когда использовать?
- 12. Когда использовать: до или: после
- 13. Когда использовать Servlet или @Controller
- 14. когда использовать ткань или правку?
- 15. Когда использовать действия или фрагменты
- 16. Когда использовать?,!, None или Lazy?
- 17. Когда использовать Server.Transfer или Response.Rewrite?
- 18. Когда использовать модель или помощник
- 19. Когда использовать moustache.js или backbone.js
- 20. Когда использовать strncpy или memmove?
- 21. Когда использовать JFrame или JPanel
- 22. Когда использовать Mock или Fake или Overrides?
- 23. Когда использовать интерфейсы или абстрактные классы? Когда использовать оба?
- 24. Когда использовать атрибуты или когда использовать свойства в python?
- 25. Почему мой маленький STRef Int требует выделения гигабайт?
- 26. Когда использовать TextFrame или TextFrame2 в VBA
- 27. Когда использовать цикл while или if?
- 28. Когда использовать явную строку или константную строку
- 29. conf или .htaccess-- когда использовать какой?
- 30. Когда использовать обратный или обратный вызов?
Последнее, IMHO, самое важное: 'ST' позволяет вам безопасно использовать императивные функции, предоставляя чистый интерфейс. –
Как точно выглядят вычисления ST внутри чистой функции? Можете ли вы привести пример побега? – user782220
@ user782220 Вы избегаете 'ST', используя функцию' runST'. На странице Haskellwiki на 'ST' есть несколько примеров: http://www.haskell.org/haskellwiki/Monad/ST См. Также расширение' RankNTypes': https://www.fpcomplete.com/school/to-infinity- и-beyond/pick-of-the-week/guide-to-ghc-extensions/explicit-forall # use-case-the-st-monad – danidiaz