Pregunta

Tengo un tipo de datos que contiene un IOREF como un elemento importante. Esto significa que no hay una forma limpia de convertirlo en miembro del show clase de tipo. Esto no es tan malo ya que tengo un print función en la monad io para este tipo. Pero es molesto en GHCI en que cada vez que devuelvo una de estas cosas como resultado, recibo un error que indica que no se puede mostrar.

¿Hay alguna forma de obtener GHCI, que funciona en el Mónada IO de todos modos, para usar una acción de IO para mostrar un resultado? Si no, ¿habría consecuencias negativas para escribir? show a = unsafePerformIO $ print a?

¿Fue útil?

Solución

¿Ha considerado agregar a su archivo .ghci algo así como:

instance (Show a) => Show (IORef a) where
    show a = show (unsafePerformIO (readIORef a))

No es seguro en absoluto, pero si esto es solo para su uso personal, tal vez esté bien.

Para un uso más general, las respuestas dadas anteriormente me parecen bien. Es decir, definir un mensaje estático "No puedo mostrar este":

instance Show (IORef a) where
    show _ = "<ioref>"

Esto daría algo como:

> runFunc
MyStruct <ioref> 4 "string val"

O use una función personalizada. Sugiero hacer una clase y levantar todas las instancias del espectáculo:

class ShowIO a where
    showIO :: a -> IO String

instance Show a => ShowIO a where
    showIO = return . show
instance ShowIO a => ShowIO (IORef a) where
    showIO a = readIORef a >>= showIO

Dando la salida (no probada, esto está solo escrito a mano):

> myFunc >>= showIO
MyStruct "My String in an IORef" 4 "string val"

Otros consejos

GHCI tiene tres casos para valores de retorno:

  1. Show a => a: Solo ejecutar el programa e imprimirlo
  2. Show a => IO a: Ejecutar la acción, ejecutar el programa e imprimir
  3. IO (): imprimir nada

Por lo general, si escribe una acción de IO, se ejecuta y el resultado se imprime si no es así (). Vamos a intentarlo:

ghci>15
15
ghci>'a' : 'b' : 'c' : []
"abc"
ghci>putStrLn "Hello, world!"
Hello, world!
ghci>putStrLn "Hello, world!" >> return 42
Hello, world!
42
ghci>

Si desea imprimir algo diferente, la mejor manera es escribir una función personalizada y pegarla frente a cada línea que desee ver:

myShowFun :: ... -> IO String

ghci> myShowFun $ ...
foobar
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top