Search code examples
haskelltypesparsec

The type signature of Parsec function 'parse' and the class 'Stream'


What does the constraint (Stream s Identity t) mean in the following type declaration?

parse :: (Stream s Identity t)
  => Parsec s () a -> SourceName -> s -> Either ParseError a

What is Stream in the following class declaration, what does it mean. I'm totally lost.

class Monad m => Stream s m t | s -> t where

When I use Parsec, I get into a jam with the type-signatures (xxx :: yyy) all the time. I always skip the signatures, load the src into ghci, and then copy the type-signature back to my .hs file. It works, but I still don't understand what all these signatures are.


EDIT: more about the point of my question.

I'm still confused about the 'context' of type-signature:

(Show a) =>

means a must be a instance of class Show.

(Stream s Identity t) => 

what's the meaning of this 'context', since t never showed after the =>


I have a lot of different parser to run, so I write a warp function to run any of those parser with real files. but here comes the problem:

Here is my code, It cannot be loaded, how can I make it work?

module RunParse where
import System.IO
import Data.Functor.Identity (Identity)
import Text.Parsec.Prim (Parsec, parse, Stream)

--what should I write "runIOParse :: ..."
--runIOParse :: (Stream s Identity t, Show a) => Parsec s () a -> String -> IO ()
runIOParse pa filename =
  do
    inh <- openFile filename ReadMode
    outh <- openFile (filename ++ ".parseout") WriteMode
    instr <- hGetContents inh
    let result = show $ parse pa filename instr
    hPutStr outh result
    hClose inh
    hClose outh

Solution

  • the constraint: (Stream s Identity t) means what?

    It means that the input s your parser works on (i.e. [Char]) must be an instance of the Stream class. In the documentation you see that [Char] is indeed an instance of Stream, since any list is.

    The parameter t is the token type, which is normally Char and is determinded by s, as states the functional dependency s -> t.

    But don't worry too much about this Stream typeclass. It's used only to have a unified interface for any Stream-like type, e.g. lists or ByteStrings.

    what is Stream

    A Stream is simply a typeclass. It has the uncons function, which returns the head of the input and the tail in a tuple wrapped in Maybe. Normally you won't need this function. As far as I can see, it's only needed in the most basic parsers like tokenPrimEx.

    Edit:

    what's the meaning of this 'context', since t never showed after the =>

    Have a look at functional dependencies. The t never shows after the ´=>´, because it is determiend by s. And it means that you can use uncons on whatever s is.

    Here is my code, It cannot be loaded, how can I make it work?

    Simple: Add an import statement for Text.Parsec.String, which defines the missing instance for Stream [tok] m tok. The documentation could be a bit clearer here, because it looks as if this instance was defined in Text.Parsec.Prim.

    Alternatively import the whole Parsec library (import Text.Parsec) - this is how I always do it.