2

我有一个 Haskell 记录数据类型,如下所示:

data Client = Client { clientId :: Int
                     , nickname :: Text
                     , clientSink :: Maybe (WS.Sink WS.Hybi00)
                     , clientRoom :: Maybe Room
                     }

我无法从中派生 Show 实例,因为 WS.Sink 没有 Show 实例。

如何制作仅排除 clientSink 字段的 Show 实例,但像普通记录一样打印其余记录字段?

我应该为 WS.Sink 创建一个自定义 Show 实例吗?

4

2 回答 2

10

为 WS.Sink 添加一个 Show 实例

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

或您想要的任何虚拟值。

于 2012-10-05T19:20:22.997 回答
7

在这种情况下,我不确定您是否真的想要 , 的实例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)
                 ++ "}"

然后如果你想把它变成一个Show实例,它就像

instance Show Client where
    show = toString
于 2012-10-05T20:31:59.170 回答