Asumamos que tenemos una acción IO comoReentrante almacenamiento en caché de "referencialmente transparente" IO llama
lookupStuff :: InputType -> IO OutputType
que podría ser algo tan simple como la búsqueda de DNS, o alguna llamada de servicio web contra un conjunto de datos invariables en el tiempo.
Vamos a suponer que:
La operación nunca se lanza ninguna excepción y/o nunca diverge
Si no fuera por la
IO
mónada, la función sería pura, es decir, el resultado es siempre igual para los parámetros de entrada igualesLa acción es reentrante, es decir, se puede invocar desde varios hilos al mismo tiempo de forma segura.
La operación
lookupStuff
es bastante (costosa).
El problema que estoy enfrentando es la manera correcta (y w/o utilizando cualquier unsafe*IO*
tramposo) implementar una memoria caché de reentrada, que pueden ser llamados desde varios subprocesos, y coalesce varias consultas para los mismos parámetros de entrada- en una sola solicitud.
Supongo que estoy buscando algo similar al concepto de agujero negro de GHC para cálculos puros pero en el contexto de "cálculo" IO.
¿Cuál es la solución Haskell/GHC idiomática para el problema indicado?
Las suposiciones 1 , 2 y 3 parecen implicar que la función es realmente pura y que la impureza es simplemente un detalle de implementación.En ese caso, no creo que haya nada de malo en usar inseguroPerformIO. De hecho, creo que InseguroPerformIO existe exactamente para tales casos. –
De acuerdo. 1, 2, 3 son suposiciones muy fuertes que casi nunca son válidas para el código en IO, pero si de hecho se puede garantizar que esto no sea seguroPerformIO es bastante razonable. –
Ok, pero ¿cómo puedo garantizar que el efecto IO nunca se realice más de una vez por el mismo argumento de entrada? – hvr