
The problem is your show instance.
show x' = show x', means that when x' is a FullState, it shows it, which
causes an infinite loop.
You need to take out the default case and add something for FullState.
On Wed, Mar 25, 2015 at 11:37 AM, Adam Flott
I'm having trouble understanding why my simple parser never terminates when specific input is used.
For example, let's say the first column is a field which can be in one of 4 states, empty, omitted, other, and any arbitrary value. That is,
data FieldState a = EmptyState | OmittedState | OtherState | FullState a deriving (Eq, Ord)
When attempting to use,
$ echo "- " | ./parser "- \n" empty ('-') $ echo "^ " | ./parser "^ \n" omitted ('^') $ echo "~ " | ./parser "~ \n" other ('~') [ all of this is as expected ] $ echo "1 " | ./parser "1 \n" [ computer twiddles it's thumbs here until I manually terminate it ... ] ^C^C $
Does anyone know what's happening and now to alleviate it?
-- begin full code --
-- base import Control.Applicative import Data.Word
-- Hackage import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.IO as TLIO import Text.Parsec (parse) import Text.Parsec.Text.Lazy (Parser) import Text.Parser.Combinators import Text.Parser.Char
data FieldState a = EmptyState | OmittedState | OtherState | FullState a deriving (Eq, Ord)
instance Functor FieldState where fmap f (FullState a) = FullState (f a) fmap _ EmptyState = EmptyState fmap _ OmittedState = OmittedState fmap _ OtherState = OtherState
instance Applicative FieldState where pure = FullState (FullState f) <*> (FullState x) = FullState (f x) _ <*> _ = EmptyState
instance Monad FieldState where (FullState x) >>= k = k x EmptyState >>= _ = EmptyState OmittedState >>= _ = OmittedState OtherState >>= _ = OtherState
(FullState _) >> k = k EmptyState >> _ = EmptyState OmittedState >> _ = OmittedState OtherState >> _ = OtherState
return = FullState fail _ = EmptyState
instance Show (FieldState x) where show (EmptyState) = "empty ('-')" show (OmittedState) = "omitted ('^')" show (OtherState) = "other ('~')" show x' = show x'
data Counter = Counter Word64 deriving (Eq, Ord, Show)
parseNum :: (Num a) => Parser a parseNum = do n <- rd <$> many digit return $ fromIntegral n where rd = read :: String -> Integer
parseCounter :: Parser Counter parseCounter = Counter <$> parseNum
parseFieldStateOff :: Parser Char parseFieldStateOff = char '-'
parseFieldStateOmitted :: Parser Char parseFieldStateOmitted = char '^'
parseFieldStateOther :: Parser Char parseFieldStateOther = char '~'
parseFieldState :: Parser a -> Parser (FieldState a) parseFieldState p = (parseFieldStateOff >> return EmptyState) <|> (parseFieldStateOmitted >> return OmittedState) <|> (parseFieldStateOther >> return OtherState) <|> (p >>= return . FullState)
main :: IO () main = do ls <- TLIO.getContents print ls mapM_ processLine (TL.lines ls)
processLine :: TL.Text -> IO () processLine line = case (parse (parseFieldState parseCounter) "" line) of Left err -> print err Right xs -> print xs
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners