Haskell从文件中读取一个Map

ast*_*fel 3 haskell

我已经写了一个文件的地图,现在我正在尝试对它进行读取.那可能吗?其中一个问题就是使用ByteString和ByteString.Char8编写和读取代码.我一直收到以下错误

fromList *** Exception: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)

我的代码如下:

import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString as BS
import qualified Data.Map as Map

type Code = Map.Map Char [Bit]

writeCode :: FilePath -> Code -> IO ()
writeCode fp tr = BS.writeFile ("code_" ++ fp)
                  (BSC.pack (show (tr :: M.Map Char [Bit])))

readCode :: FilePath -> IO Code
readCode f = do s <- BS.readFile ("code_" ++ f)
                let s' = BSC.unpack s
                return (read s' :: Code)
Run Code Online (Sandbox Code Playgroud)

Mic*_*its 5

问题是你覆盖了Show的默认实现,但是依赖于Read的默认实现,它需要"One"或"Zero",而不是"1"或"0".

解决方案是编写自己的Read实现(你可以保留Eq和Ord):

import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString as BS
import qualified Data.Map as Map

data Bit = One | Zero deriving (Eq,Ord)

instance Show Bit where
  show One = "1"
  show Zero = "0"

instance Read Bit where
  readsPrec _ ('1':xs) = [(One, xs)]
  readsPrec _ ('0':xs) = [(Zero, xs)]
  readsPrec _ _        = []

type Code = Map.Map Char [Bit]

writeCode :: FilePath -> Code -> IO ()
writeCode fp tr = BS.writeFile ("code_" ++ fp) (BSC.pack (show tr))

readCode :: FilePath -> IO Code
readCode f = do s <- BS.readFile ("code_" ++ f)
                let s' = BSC.unpack s
                return (read s' :: Code)
Run Code Online (Sandbox Code Playgroud)