Haskell 显示IO类型
我有一个数据类型,其中包含一个IORef作为一个重要元素。这意味着没有一种干净的方法使其成为Haskell 显示IO类型,haskell,ghci,io-monad,ioref,unsafe-perform-io,Haskell,Ghci,Io Monad,Ioref,Unsafe Perform Io,我有一个数据类型,其中包含一个IORef作为一个重要元素。这意味着没有一种干净的方法使其成为showtype类的成员。这还不算太糟,因为对于这种类型,我在IO monad中有一个print函数。但在GHCi中很烦人,因为每次我返回这些东西中的一个,结果都会得到一个错误,说明它无法显示 有没有办法让在IO monad中运行的GHCi使用IO操作来显示结果?如果没有,编写show a=unsafePerformIO$print a是否会有任何负面后果 ghci的返回值有三种情况: Show a=>a
show
type类的成员。这还不算太糟,因为对于这种类型,我在IO monad中有一个print
函数。但在GHCi中很烦人,因为每次我返回这些东西中的一个,结果都会得到一个错误,说明它无法显示
有没有办法让在IO monad中运行的GHCi使用IO操作来显示结果?如果没有,编写
show a=unsafePerformIO$print a
是否会有任何负面后果 ghci的返回值有三种情况:
Show a=>a
:只需运行Show并打印即可Show a=>IO a
:执行操作,运行Show并打印IO()
:不打印任何内容()
,结果将被打印出来。让我们试试看:
ghci>15
15
ghci>'a' : 'b' : 'c' : []
"abc"
ghci>putStrLn "Hello, world!"
Hello, world!
ghci>putStrLn "Hello, world!" >> return 42
Hello, world!
42
ghci>
如果要打印不同的内容,最好的方法可能是编写一个自定义函数,并将其粘贴在您希望看到的每一行的前面:
myShowFun :: ... -> IO String
ghci> myShowFun $ ...
foobar
您是否考虑过向.ghci文件中添加以下内容:
instance (Show a) => Show (IORef a) where
show a = show (unsafePerformIO (readIORef a))
> runFunc
MyStruct <ioref> 4 "string val"
这是不安全的,但如果这只是为了你的个人使用,也许这是好的
对于更一般的用途,我觉得前面给出的答案很好。也就是说,定义一条静态“我不能显示此”消息:
给出输出(未测试,这只是手写):
据我所知,没有办法告诉ghci使用不同于
show
的函数来显示结果。但是,您可以为数据类型定义一个show实例,该实例仅为ioref显示“”或类似内容。这可能比使用unsafePerformIO
稍微干净一些,如果不方便的话。请注意,这些ShowIO
实例需要重叠实例扩展。这是相当狡猾的,尽管可能比unsafePerformIO
更狡猾。当然有助于发展。
> runFunc
MyStruct <ioref> 4 "string val"
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
> myFunc >>= showIO
MyStruct "My String in an IORef" 4 "string val"