2

私は次のような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インスタンスを作成する必要がありますか?

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のではなく、好みの問題です。

コンテキストによっては(大げさな推測をして、どこかに中間値を出力してデバッグしようとしていますか?)、別の型クラスを定義して-liketoString関数を実装すると、インスタンスの機能について誤解を招く可能性がなく、最適に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 に答える