DavidWebb
DavidWebb

Reputation: 181

Parse a String using Parsec?

I am trying to parse a String using parsec in Haskell, however every attempt throws another type of error.

import Text.ParserCombinators.Parsec
csvFile = endBy line eol
line = sepBy cell (char ',')
cell = many (noneOf ",\n")
eol = char '\n'

parseCSV :: String -> Either ParseError [[String]]
parseCSV input = parse csvFile "(unknown)" input

This code, when run through stack ghci produces an error saying "non type-variable argument in the constraint: Text.Parsec.Prim.Stream"

Basically, I am wondering what the most straight forward way to parse a String into tokens based on commas is in Haskell. It seems like a very straightforward concept and I assumed that it would be a great learning experience, but so far it has produced nothing but errors.

Upvotes: 0

Views: 600

Answers (1)

bergey
bergey

Reputation: 3081

The error I see when entering char '\n' in ghci is:

<interactive>:4:1: error:
• Non type-variable argument
    in the constraint: Text.Parsec.Prim.Stream s m Char
  (Use FlexibleContexts to permit this)
• When checking the inferred type
    it :: forall s (m :: * -> *) u.
          Text.Parsec.Prim.Stream s m Char =>
          Text.Parsec.Prim.ParsecT s u m Char

The advice about FlexibleContexts is accurate. You can turn on FlexibleContexts like so:

*Main> :set -XFlexibleContexts

Unfortunately, the next error is • No instance for (Show (Text.Parsec.Prim.ParsecT s0 u0 m0 Char)) (basically, we can't print a function) so you'll still need to apply the parser to some input to actually run it.

Like commenters, I find that parseCSV can be used without any language extensions.

There are a few things going on here:

  • In the context of the whole program, the type of eol is constrained by the type signature on parseCSV. That doesn't happen when typing eol = char '\n' into GHCi.

  • GHCi's :t is permissive - it's willing to print some types that use language features that aren't turned on.

  • GHC has grown by adding a large number of language extensions, which can be turned on by the programmer on a per-module basis. Some are widely used by production-ready libraries, others are new & experimental.

Upvotes: 1

Related Questions