我有一个看起来像这样的Haskell记录数据类型:
data Client = Client { clientId :: Int
, nickname :: Text
, clientSink :: Maybe (WS.Sink WS.Hybi00)
, clientRoom :: Maybe Room
}
由于WS.Sink没有Show实例,我无法从中导出Show实例。
如何创建一个仅排除clientSink字段的Show实例,但打印其他记录字段(如普通记录)?
我应该只为WS.Sink创建一个自定义Show实例吗?
答案 0 :(得分:6)
为WS.Sink添加Show实例
instance Show WS.Sink where show a = "Sink"
或任何你想要的虚拟值。
答案 1 :(得分:6)
在这种情况下,我不确定你真的想要一个Show
的实例。来自the docs。
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)
++ "}"
然后,如果您想将其转换为Show
实例,就像
instance Show Client where
show = toString