这个问题可能听起来微不足道,但我是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