Show IO Types

I have a data type that contains IORef as an important element. This means that there is no clean way to make it a member of a class like show . This is not so bad since I have a print function in the IO monad for this type. But this is annoying in GHCi, because every time I return one of these things, I get a message that it cannot be displayed.

Is there a way to get a GHCi that works in the IO monad anyway to use the I / O result to show the result? If not, will there be any negative consequences for writing show a = unsafePerformIO $ print a ?

+7
source share
2 answers

You thought you were adding something like this to your .ghci file:

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

This is unsafe, but if it is only for your personal use, perhaps this is normal.

For more general use, the previous answers work well for me. That is, either set the static message "I cannot show this":

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

This will give something like:

 > runFunc MyStruct <ioref> 4 "string val" 

Or use a custom function. I suggest making a class and removing all instances of Show:

 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 

Providing output (untested, this is only handwritten text):

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

ghci has three cases for return values:

  • Show a => a : just start the show and print it
  • Show a => IO a : complete the action, start the show and print
  • IO () : don't print anything

Typically, if you enter an I / O action, it is executed, and the result is printed if it is not () . Let's try:

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

If you want to print something else, the best way is probably to write a custom function and insert it before each line you want to see:

 myShowFun :: ... -> IO String ghci> myShowFun $ ... foobar 
+2
source

All Articles