如何将parsec的结果存储在Haskell的列表中?

时间:2015-06-11 19:26:01

标签: haskell parsec

这个问题可能听起来微不足道,但我是Haskell的初学者,我已经阅读了一些parsec的教程,但是无法弄清楚如何将解析器的结果存储在列表中(或者在我的情况下是字符串列表)。

以下是解析器的代码:

-- Adapted from http://book.realworldhaskell.org/read/using-parsec.html -> ch16/csv9.hs and ch16/csv6.hs
import Text.ParserCombinators.Parsec

pgmFile = endBy line eol
line = sepBy cell (char ' ')
cell = many (noneOf " \n")

eol =   try (string "\n\r")
    <|> try (string "\r\n")
    <|> string "\n"
    <|> string "\r"
    <?> "end of line"

parsePGM :: String -> Either ParseError [[String]]
parsePGM input = parse pgmFile "(unknown)" input

main =
    do c <- getContents
       case parse pgmFile "(stdin)" c of
            Left e -> do putStrLn "Error parsing input:"
                         print e
            Right r -> mapM_ print r
{-- /snippet all --}


returnString = 
    do c <- getContents
       case parse pgmFile "(stdin)" c of
            Left e -> do putStrLn "Error parsing input:"
                         print e
            Right r -> r

returnString函数不起作用,但main函数接受ascii pgm文件并在字符串列表中解析它,其中每一行都是一个列表,而单词是列表的内容。 我想将结果列表存储在一个变量中,以便以后使用它。 那我该怎么做呢?

我非常感谢能得到的每一个帮助!

编辑: 函数returnString的错误消息是:

pgmCH9.hs:32:24:
    Couldn't match type ‘[]’ with ‘IO’
    Expected type: IO ()
      Actual type: [[[Char]]]
    In the expression: r
    In a case alternative: Right r -> r

我想这正是莎拉在评论中写的。左侧和右侧的类型必须相同。主Right的输出看起来像我想要存储的列表,这就是为什么我试图在返回值的帮助下保存它。

这是解析pgmFile的类型&#34;(stdin)&#34;:

ghci> :type parse pgmFile "(stdin)"
parse pgmFile "(stdin)" :: [Char] -> Either ParseError [[[Char]]]

Edit2:所以这里是修改后的代码,其中添加了基于评论的内容:

-- Adapted from http://book.realworldhaskell.org/read/using-parsec.html -> ch16/csv9.hs and ch16/csv6.hs
import Text.ParserCombinators.Parsec
import System.IO 

-- 

{- A PGM file contains a header witht the type, a comment, the width and height of the picture
   and the maximum value for all pixels. The picture presists of width*height pixels, each of
   which is seperated by a space or the end-of-line character (eol). -}
--pgmFile :: Text.Parsec.Prim.ParsecT [Char] u Data.Functor.Identity.Identity [[[Char]]]
pgmFile = endBy line eol

-- Each line contains 1 or more pixels, separated by a space
--line :: Text.Parsec.Prim.ParsecT [Char] u Data.Functor.Identity.Identity [[Char]]
line = sepBy pixel (char ' ')

-- Each pixel contains of characters and is limited by space or a newline
--pixel :: Text.Parsec.Prim.ParsecT [Char] u Data.Functor.Identity.Identity [Char]
pixel = many (noneOf " \n")


--eol :: Text.Parsec.Prim.ParsecT [Char] u Data.Functor.Identity.Identity String
eol =   try (string "\n\r")
    <|> try (string "\r\n")
    <|> string "\n"
    <|> string "\r"
    <?> "end of line"

parsePGM :: String -> Either ParseError [[String]]
parsePGM input = parse pgmFile "(unknown)" input

main :: IO ()
main =
    do c <- getContents
       case parse pgmFile "(stdin)" c of
            Left e -> do putStrLn "Error parsing input:"
                         print e
            Right r -> mapM_ print r

returnString :: IO ()
returnString = 
    do c <- readFile "test_ascii.pgm"
       case parse pgmFile "(stdin)" c of
            Left e -> do putStrLn "Error parsing input:"
                         print e
            Right r -> print r

0 个答案:

没有答案