On Sat, 2008-02-02 at 20:43 -0600, Antoine Latter wrote: > On Feb 2, 2008 5:28 PM, Antoine Latter <[EMAIL PROTECTED]> wrote: > > I'm not a fan of parameterizing the "Stream" class over the monad parameter > > `m': > > > > > class Stream s m t | s -> t where > > > uncons :: s -> m (Maybe (t,s)) > > > > which leads to instance declarations like so: > > > > > instance Monad m => Stream [tok] m tok where > > > uncons [] = return $ Nothing > > > uncons (t:ts) = return $ Just (t,ts) > > > > To expand on this point, side-effect instances of Stream don't play > nice with the backtracking in Text.Parsec.Prim.try: > > > import Text.Parsec > > import Text.Parsec.Prim > > import System.IO > > import Control.Monad > > > type Parser a = (Stream s m Char) => ParsecT s u m a > > This particular instance was suggested by Derek. > > > instance Stream Handle IO Char where > > uncons hdl = do > > b <- hIsEOF hdl > > if b then return Nothing > > else liftM (\c -> Just (c,hdl)) getChar > > > testParser :: Parser String > > testParser = try (string "hello1") <|> string "hello2" > > > test1 = runPT testParser () "stdin" stdin >>= print > > test2 = hGetLine stdin >>= print . runP testParser () "stdin" > > "test1" uses the (Stream Handle IO Char) instance, "test2" uses the > (Monad m => Stream [a] m a) instance. > > For input "hello2", test2 produces a valid parse while test1 does not.
Note that instance has a typo in it (which I fixed before testing this myself): getChar should be (hGetChar hdl) (though that makes no difference when you pass in stdin) _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe