voltaje usar salida pines pin gnd entrada haskell state monads ioref

haskell - salida - ¿Cuándo está bien usar un IORef?



pines de arduino (4)

El estado y su ST relativo producen cálculos estadísticos "monolíticos" que pueden ejecutarse como unidades. Básicamente tratan el estado mutable como datos intermedios, que se necesitan para producir un resultado, pero no deberían, en sí mismos, ser de interés para el resto del programa.

Por otro lado, lo que uno pone dentro de un IORef no es un ''cálculo'' para ser ejecutado; es solo un cuadro que contiene un valor simple que puede usarse dentro de IO de maneras bastante arbitrarias. Este recuadro puede colocarse dentro de las estructuras de datos, pasar alrededor de la porción (IO) del programa, reemplazar sus contenidos cuando sea conveniente, ser cerrado por una función, etc. De hecho, es bastante desordenado la naturaleza de las variables y los punteros de lenguajes como C podrían modelarse con IORefs, proporcionando gran asistencia a cualquier programador C experto que desee mantener su reputación de poder escribir código C en cualquier idioma ... Esto es algo que definitivamente debe usarse con cuidado.

Aún así, a veces es extremadamente difícil de manejar, si no completamente imposible, aislar todas las interacciones con un estado mutable en un solo bloque de código: algunas piezas de estado simplemente deben pasarse, ponerse dentro de estructuras de datos, etc. En los casos, el enfoque de caja puede ser la única opción. El capítulo que presenta el estado mutable del tutorial Write Yourself a Scheme en 48 Horas (muy recomendable, por cierto) proporciona un ejemplo. (Consulte el enlace para ver una buena discusión sobre por qué es realmente más apropiado usar IORefs, en lugar de State o ST, para modelar entornos Scheme en un determinado diseño de un intérprete Scheme).

En resumen, esos entornos deben anidarse de manera arbitraria, manteniéndose entre instancias de interacción del usuario (un (define x 1) escrito en el esquema REPL probablemente resulte en que el usuario pueda escribir más adelante x y recuperar 1 como el valor), coloque objetos internos que modelen las funciones del esquema (dado que las funciones del esquema se cierran sobre los entornos en los que se crean), etc.

Para resumir, diría que si una tarea parece adecuada para ella, State tenderá a proporcionar la solución más limpia. Si se necesitan múltiples piezas de estado por separado, quizás ST puede ayudar. Sin embargo, si el cálculo con estado es difícil de manejar o imposible de bloquear en su propia pieza de código, el estado debe persistir en una forma modificable durante gran parte de la vida de un programa complejo, etc., entonces IORefs puede ser solo el lo apropiado

Por otra parte, si uno necesita el tipo de estado mutable que puede transmitirse e interactuar de forma controlada por el código IO, ¿por qué no echa un vistazo a STM y sus TVars? Son mucho más agradables en presencia de concurrencia, tanto, de hecho, que simplifican la resolución de algunas tareas relacionadas con la concurrencia. Sin embargo, esto no está realmente relacionado con la pregunta, así que me resistiré a insistir en la elaboración. :-)

Una cosa que siempre me ha confundido es si es o no un buen momento para usar un IORef. ¿Hay alguna guía que se debe seguir al decidir si usar o no un IORef para una tarea? ¿Cuándo es un buen momento para usar la mónada estatal sobre un IORef?


Hmm. Utilizaría un IORef cuando necesite algún estado mutable, pero se encuentre en un entorno con un solo subproceso. O cuando desea un campo mutable dentro de una estructura más grande que a su vez está en manos de una variable de sincronización.

En general, usa MVars. Tienen una semántica más robusta.


Personalmente, diría que está bien usar IORef s cuando y solo cuando ya está usando IO . De lo contrario, siempre State , a menos que necesites el rendimiento superior de ST . Es posible utilizar múltiples hilos de estado con la mónada de State , con algunas funciones auxiliares: simplemente convierte el estado en una tupla o registro, y define funciones para establecer, obtener o actualizar cada campo por separado.

En particular, no suele haber mucho sentido en el uso de StateT s IO . Si ya está en IO , ya tiene un estado mutable, por lo que también podría usarlo: ReaderT (IORef s) IO por ejemplo.


Uso STRef cuando el estado está localizado y no requiere interacción con el entorno.