Domanda

Ho un tipo di dati che contiene un IOREF come un elemento importante. Ciò significa che non v'è un modo pulito per renderlo un membro della classe di tipo show. Questo non è troppo male come Ho una funzione print nella monade IO per questo tipo. Ma è fastidioso in GHCi in quanto ogni volta che ritorno uno di questi cosa come un risultato che ottengo un errore che indica che non può essere mostrato.

C'è un modo per ottenere GHCi, che opera nel IO Monade in ogni caso, per utilizzare un'azione IO per mostrare un risultato? In caso contrario, ci sarebbero conseguenze negative per la scrittura show a = unsafePerformIO $ print a?

È stato utile?

Soluzione

Avete considerato di aggiungere al vostro file di qualcosa di simile .ghci:

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

Non è sicuro a tutti, ma se questo è solo per uso personale, forse che è OK.

Per l'uso più generale le risposte date in precedenza guardare bene a me. Cioè, sia definire una statica "non posso mostrare questo" messaggio:

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

Questo darebbe qualcosa di simile:

> runFunc
MyStruct <ioref> 4 "string val"

o utilizzare una funzione personalizzata. Suggerisco di fare una classe e sollevare tutte le istanze Mostra:

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

Dare l'uscita (non testato, questo è solo scritto a mano):

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

Altri suggerimenti

ghci ha tre casi per i valori di ritorno:

  1. Show a => a: basta eseguire spettacolo e stamparlo
  2. Show a => IO a: eseguire l'azione, corsa spettacolo e Stampa
  3. IO (): print niente

Quindi, di solito, se si digita l'azione IO, di venire di eseguita e il risultato viene stampato se non è (). Proviamo:

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

Se si desidera stampare qualcosa di diverso, il modo migliore è probabilmente quello di scrivere una funzione personalizzata e bastone di fronte a ogni riga che si desidera visualizzare:

myShowFun :: ... -> IO String

ghci> myShowFun $ ...
foobar
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top