0
votes

I Need to parse a String into Array of Arrays. String is splited in Arrays by "\n" char. And each of that Array is splited by "," or ";" signs.

Example: 4;5\n6,7 -----> [[4,5][6,7]]

import qualified Text.Parsec as P (char,runP,noneOf,many,(<|>),eof)
import Text.ParserCombinators.Parsec
import Text.Parsec.String 
import Text.Parsec.Char
import Text.PrettyPrint.HughesPJ
import Data.Maybe

newtype CSV = CSV [Row] deriving (Show,Eq)
type Row = [String]

parseCSV :: Parser CSV
parseCSV = do
  return $ CSV (endBy (sepBy (many (noneOf ",\n")) (Text.Parsec.Char.char ',')) (Text.Parsec.Char.char '\n'))

runParsec :: Parser a -> String -> Maybe a
runParsec parser input = case P.runP parser () "" input of
    Left  _ -> Nothing
    Right a -> Just a

But when I try to run the Code I get error because of wrong data types

1
I believe all the Parsec functions are monadic and should be used in a do block, not by passing them as arguments to each other like that. It certainly isn't going to work with your CSV type since it expects [[String]] and not some Parsec type.bheklilr
bhekillar you are right :(John Doe
@bheklilr you mean CSV <$> endBy (...) right?Alec
@Alec I definitely mean <$>, this is what happens when I don't write as much Haskell as I used to... I just deleted that comment since it was outside of the edit window.bheklilr

1 Answers

2
votes

Here is a solution that parses runParsec parseCSV "4;5\n6,7\n" into Just (CSV [["4","5"],["6","7"]]).

parseCSV :: Parser CSV
parseCSV = CSV <$> csv
  where
    csv = row `endBy` char '\n'
    row = many (noneOf ",;\n") `sepBy` oneOf ",;"