2015-12-10 3 views
3

Я написал карту в файл и теперь пытаюсь выполнить чтение на ней. Это возможно? Один ключ в том, что код написан и читается с помощью ByteString и ByteString.Char8. Я получаю следующее сообщение об ошибкеHaskell читает карту из файла

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

Мой код выглядит следующим образом:

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) 
+0

Можете ли вы данный пример 'Code' вы стремитесь писать в файл, так что ошибка может быть * воспроизведена *? –

+0

'fromList [('e', [1,1,0]), ('h', [1,1,1]), ('l', [0]), ('o', [1, 0])] является одним из примеров. Когда я написал его в файл, это то, как он появляется в файле, но теперь я не могу его прочитать. Извините, бит - это тип данных с одним или с нуля, представленный 1 или 0 – astiefel

+0

. Я получаю * Не в области: введите конструктор или класс «Бит» *. :( –

ответ

5

Проблема заключается в том, что вы переопределить реализацию по умолчанию Show, но полагаться на реализацию по умолчанию Read, который ожидает " Один »или« Ноль », а не« 1 »или« 0 ».

Решение написать собственную реализацию Read (вы можете оставить уравнение и 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) 
+0

Большое спасибо. Я никогда не переопределял чтение до этого, так что это дает мне предупреждение о следующем шаблоне, не совпадающем: '_ ((GHC.Types.C# #x): _) с #x notElem ['1', '0']'. Есть ли способ просто сказать, чтобы он действовал с его нормальным чтением? – astiefel

+1

В экземпляре Read отсутствовал случай, я обновил свой ответ. –

Смежные вопросы