Defined in Prelude
,
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
In short, these are the standard "serialization" methods in Haskell. show :: (Show a) => a -> String
can turn anything that is an instance of Show
into a string, and read :: (Read a) => String -> a
can turn a string into anything that is an instance of Read
(or throw an exception).
Most of the built-in types and data structures in the standard library have Show
and Read
instances defined; if you're composing parts from them, your type also has Show
and Read
instances defined.
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)
If Table
were a datatype, you have to ask for the instances, but you can request that the compiler automatically derive them for you.
data Table = Table [(String, String)]
deriving (Read, Show)
Sometimes that's not possible and you have to define your own instances.
instance Show Table where
showsPrec p x = ...
instance Read Table where
readsPrec p x = ...
But that shouldn't be common.