我有一个Haskell记录数据类型,如下所示:
data Client = Client { clientId :: Int
, nickname :: Text
, clientSink :: Maybe (WS.Sink WS.Hybi00)
, clientRoom :: Maybe Room
}
Run Code Online (Sandbox Code Playgroud)
我无法从中导出Show实例,因为WS.Sink没有Show实例.
如何创建一个仅排除clientSink字段的Show实例,而是打印其他记录字段,如普通记录?
我应该只为WS.Sink创建一个自定义Show实例吗?
小智 7
为WS.Sink添加Show实例
instance Show WS.Sink where show a = "Sink"
Run Code Online (Sandbox Code Playgroud)
或者你想要的虚拟价值.
小智 6
Show
在这种情况下,我不确定你真的想要一个实例.来自文档.
Show的派生实例具有以下属性,这些属性与Read的派生实例兼容:
- show的结果是一个语法正确的Haskell表达式,只包含常量,给定声明类型的点处的强制声明.它仅包含数据类型,括号和空格中定义的构造函数名称.使用标记的构造函数字段时,还使用大括号,逗号,字段名称和等号.
这确实伴随着它仅适用于派生实例的警告,但我是契约的坚持者,并且习惯于假设它read . show
实际上是无操作.当你试图自动派生一个实例时,你会再遇到同样的问题Read
,所以现在使用它不会引入语义错误Show
,这只是一个偏好问题.
根据你的上下文(猜测,你试图通过在某处打印中间值来调试?)定义另一个类型类并实现类似toString
函数可能最适合你,而不会对show
你的实例的功能产生误导.例如,
class ToString a where
toString :: a -> String
instance ToString Client where
toString c = "Client {"
++ shows (clientId c) ", "
++ shows (nickname c) ", "
++ shows (isJust (clientSink c)) ", "
++ show (clientRoom c)
++ "}"
Run Code Online (Sandbox Code Playgroud)
然后如果你想把它变成一个Show
实例就像它一样简单
instance Show Client where
show = toString
Run Code Online (Sandbox Code Playgroud)