Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell read a Map from file

Tags:

haskell

I have written a map to a file and now am trying to perform a read on it. Is that possible? One wrench in there is that the code is written and read using ByteString and ByteString.Char8. I keep getting the following error

fromList *** Exception: Prelude.read: no parse

My code is as follows:

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)
like image 299
astiefel Avatar asked Dec 06 '25 15:12

astiefel


1 Answers

The problem is that you override the default implementation of Show, but rely on the default implementation of Read, which expects "One" or "Zero", not "1" or "0".

The solution is to write your own implementation of Read (you can leave Eq and Ord as it is):

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)
like image 87
Michael Szvetits Avatar answered Dec 08 '25 16:12

Michael Szvetits



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!