如何自定义Haskell记录的Show实例



我有一个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实例吗?

为WS-Sink 添加Show实例

instance Show WS.Sink where show a = "Sink"

或者你想要的任何伪值。

在这种情况下,我不确定您是否真的想要Show的实例。来自文档。

Show的派生实例具有以下属性,这些属性与Read的派生实例兼容:

  • show的结果是一个语法正确的Haskell表达式,它只包含常量,给定在声明类型时有效的固定性声明。它只包含在数据类型、圆括号和空格中定义的构造函数名称。使用带标签的构造函数字段时,还会使用大括号、逗号、字段名和等号

这确实附带了一个警告,即它只适用于派生实例,但我坚持契约,并且已经习惯于假设read . show实际上是一个no-op。当然,在尝试自动派生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

最新更新