3

read someValue :: someDataTypeorは宣言に書かなければならないshow someValueので、すべての型に対して行うことはできません。間違い以外に、型をシリアライズ可能にしたくない場合はありますか? Show が Read から分離されているのはなぜですか? 間違い以外に、一部のデータを表示したいだけで読みたくない場合はありますか? そうでない場合、単一のデータ型を持たないのはなぜですか?deriving (Show, Read)dataSerializable

ちょうど今、Gloss ライブラリKeyデータ型を使用していますが、これはわかりませんShowReadコントロールの構成をファイルに入れてから読みたかったので、プレーヤーがコントロールを変更して独自の構成を持つことができるようにしたかったので残念です。Key、SpecialKey、MouseButton のラッパーを作成する必要がありましたが、これは大したことではありませんが役に立ちません。

data Key' = Char' Char | SpecialKey' SpecialKey | MouseButton' MouseButton
    deriving (Eq, Ord, Show, Read)
convertKey x = case x of
    Char' c -> Char c
    SpecialKey' sk -> SpecialKey sk
    MouseButton' mb -> MouseButton mb
4

3 に答える 3

11

まず、すべてのデータ型を表示できるわけではありません。たとえば、関数を表示できないため、すべてのデータ型を表示(または読み取り)できるわけではありません。元のHaskellの定義では、派生句が指定されていない場合、可能な限り多くの派生クラスが派生することが指定されていました。これにより、実際に派生したクラスを知ることが困難になったため、Haskellの定義が変更され、明示的な派生句が強制されました。

第二に、元のHaskell定義では、showand関数はクラスread内で一緒にバンドルされています。これは、派生して作成Textする場合はそれほど問題にはなりませんが、手書きで作成する場合は面倒です。特別な関数を定義したいことがよくありますが、今では関数も作成する必要があるため、それらを分離しておくことをお勧めします。個人的に私はほとんど常に派生しますが、ほとんど決して派生しません。ShowReadshowreadShowRead

Showandクラスは、Read実際にはシリアル化に使用することを意図したものではなく、単純な入力と出力に使用することを目的としています。

于 2012-07-04T17:39:14.077 に答える
10

Show が Read と異なる理由

なぜこれが元々あったのかはわかりませんが、一部の (ごく少数の) 型を表示できるか、プレースホルダー文字列を表示できても読み戻せないため、永続化する必要があると感じています。関数は典型的な例です。

別の考え方: 物事を別々のクラスに配置するのは非常に簡単ですが、1 つのクラスであまりにも多くの関数を処理するのは非常に難しく、同じコンテキストでは必ずしも意味がありません。多くの人は、Numクラスがこの問題の典型的な例だと感じています。

どうすればreadキーやその他のタイプがないRead

Readステップ 1:一連の派生インスタンスに追加するパッチを送信します。ステップ 2: スタンドアロンの派生を使用して回避策を作成します。

{-# LANGUAGE StandaloneDeriving #-}
deriving instance Show Key

ステップ 3: CPP を使用して、いずれかのバージョンのコードベースでコードが機能するようにします。それは、Ben がいつかリリースする Read インスタンスを含む Gloss ライブラリか、ないバージョンです。

Serializableなぜクラスがないのですか?

まず、Serialize クラスがあります。また、テキストは物事をシリアライズする恐ろしい方法です。おそらく、レイジーなシリアル化クラスが必要な場合は、Binary クラスが表示されるはずです。パフォーマンスが気になるなら、blaze-builderが好きかもしれませんが、私は正直言って使ったことはありません。

于 2012-07-04T17:29:47.717 に答える
7

すべての型がシリアライズ可能というわけではありません。String -> Stringとの間の同形性をどのように確立できますStringか? Readと のShowインスタンスを指定するString -> Stringと、次のようにシリアル化できない関数を見つけることができます。

evil :: String -> String
evil s = map succ (read s s ++ " evil")

仮定する

read (show evil) = evil

我々が得る

evil (show evil)
  = map succ (read (show evil) (show evil) ++ " evil")
  = map succ (evil (show evil) ++ " evil")
  = map succ (evil (show evil)) ++ "!fwjm"

したがって、evil (show evil)が定義されている場合、最初の文字cが を満たすことになりますがc = succ c、これは不可能です。

通常、関数はシリアル化できません。関数をまとめたデータ型を書くこともあるので、すべてのデータ型がシリアライズ可能というわけではありません。例えば、

data Psychiatrist
  = Listen (String -> Psychiatrist)
  | Charge Int

場合によっては、これらの型についても、部分的な実装Read(一部のケースが欠落している) とShow(たとえば、関数のプレースホルダーまたは表) を提供することを選択する場合がありますが、それらを選択する標準的な方法や、両方を期待する理由はありません。 .

他の人が述べたように、深刻なシリアライゼーションはSerialize. Show私は診断目的でandを使用する傾向がありRead、特に ghci で試してみます。ghci には読み取りを行うHaskellパーサーがあるため、その目的にShowははるかに便利です。

于 2012-07-04T17:56:00.903 に答える