、要するに
type ShowS = String -> String
class Show a where
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
type ReadS a = String -> [(a, String)]
class Read a where
readsPrec :: Int -> ReadS a
readList :: ReadS [a]
read :: (Read a) => String -> a
、これらは、Haskellでは、標準の "直列化" の方法です。 show :: (Show a) => a -> String
は、文字列にShow
のインスタンスである何かを変えることができ、かつread :: (Read a) => String -> a
はRead
(または例外をスロー)のインスタンスであるものに文字列を変えることができます。
標準ライブラリのほとんどの組み込み型およびデータ構造体には、Show
およびRead
のインスタンスが定義されています。あなたがそれらの部品を構成している場合、あなたのタイプも定義Show
とRead
インスタンスがあります。
type Table = [(String, String)]
load :: (Read a) => FilePath -> IO a
load f = do s <- readFile f
return (read s)
save :: (Show a) => a -> FilePath -> IO()
save x f = writeFile f (show x)
Table
がデータ型だった場合は、インスタンスをお願いする必要がありますが、あなたは、コンパイラが自動的にあなたのためにそれらを導出することを要求することができます。
data Table = Table [(String, String)]
deriving (Read, Show)
時にはそれは不可能ですし、あなた自身のインスタンスを定義する必要があります。
instance Show Table where
showsPrec p x = ...
instance Read Table where
readsPrec p x = ...
しかし、それは一般的ではありません。
バイナリを導出するために、http://repetae.net/computer/haskell/DrIFT/が気に入っています。つまり、この単純なケースでは、RevListのインスタンスをもっとスマートに読み書きすることは可能ですが、スケーラビリティが問題になるまで、OPは単純に固執する必要があります。 – ephemient