Сериализация структур данных в файл с Haskell? - PullRequest
1 голос
/ 16 ноября 2010

Я новичок в Haskell и пытаюсь понять, как работает IO.У меня есть структура данных, дерево, которое я хочу сериализовать в файл, а затем десериализовать обратно в структуру данных.Кажется, что я должен быть в состоянии сделать это с помощью шоу и чтения, но мое использование чтения вызывает ошибку.Вот соответствующая часть моего кода:

data Tree = Answer String | Question String Tree Tree deriving (Read, Show)

fileToTree :: (Read a) => FilePath -> IO a
fileToTree filePath = do 
    dataStruct <- readFile filePath
    return (read dataStruct)

treeToFile :: (Show a) => a -> FilePath -> IO ()
treeToFile dataStruct filePath = do
    writeFile filePath (show dataStruct)

main = do
    let filePath = "data.txt"
    let ds = fileToTree filePath
    ask ds
    treeToFile ds filePath

ask :: Tree -> IO ()
ask (Question q yes no) = do
    putStrLn q
    answer <- getLine

Ошибка, которую я получаю: «Не удалось сопоставить ожидаемый тип« Дерево »с предполагаемым типом« IO a »в первом аргументе« спросить »»,Кажется, что чтение должно возвращать тип дерева, но оно возвращает тип ввода-вывода.Есть ли способ привести его к типу Tree, или я полностью неправильно понял проблему?

1 Ответ

2 голосов
/ 16 ноября 2010

Обратите внимание, что fileToTree возвращает значение в IO.Это означает, что строка let ds = fileToTree filePath связывает IO a с идентификатором ds.Если вы хотите работать со значением, полученным в монаде IO, вам необходимо использовать функцию >>= (связывание) из монады IO, заменив строку let ds = fileToTree filePath на ds <- fileToTree filePath.Это будет связывать что-то типа a с ds, в некотором смысле снимая внешнее IO.Звонок на ask в конечном итоге объединит a с Tree.

. После этого, похоже, возникла проблема с ask.То, что у вас есть выше, не компилируется, и кажется, что вы не используете answer, поэтому я предполагаю, что это была ошибка при вставке вашего кода.

...