显示IO类型

Joh*_*ler 7 haskell ghci unsafe-perform-io io-monad ioref

我有一个数据类型,其中包含IORef作为一个重要元素.这意味着没有一种干净的方法可以使它成为show类型类的成员.这不是太糟糕,因为我print在这种类型的IO monad中有一个函数.但是在GHCi中很烦人,因为每当我返回其中一个东西时,我都会收到错误声明它无法显示.

有没有办法让IOC无论如何在IO monad中运行,使用IO动作来显示结果?如果没有,是否会对写作产生任何负面影响show a = unsafePerformIO $ print a

Tho*_*son 11

您是否考虑过将以下内容添加到.ghci文件中:

instance (Show a) => Show (IORef a) where
    show a = show (unsafePerformIO (readIORef a))
Run Code Online (Sandbox Code Playgroud)

它根本不安全,但如果这仅供您个人使用,那也许没问题.

对于更一般的使用,先前给出的答案对我来说很好.也就是说,要么定义一个静态的"我不能显示这个"消息:

instance Show (IORef a) where
    show _ = "<ioref>"
Run Code Online (Sandbox Code Playgroud)

这会给出类似的东西:

> runFunc
MyStruct <ioref> 4 "string val"
Run Code Online (Sandbox Code Playgroud)

或使用自定义功能.我建议创建一个类并解除所有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
Run Code Online (Sandbox Code Playgroud)

给出输出(未经测试,这只是手写):

> myFunc >>= showIO
MyStruct "My String in an IORef" 4 "string val"
Run Code Online (Sandbox Code Playgroud)