Robert Onslow
Robert Onslow

Reputation: 215

Haskell Read - no parse error

I have a type called PartialDate

Then I have a function

readPartialDate :: String -> Maybe PartialDate

Bit of test code

main = do
        [d] <- getArgs
        return $ show $ readPartialDate d 
runhaskell PartialDate.hs "12-2-2010"
"Just 12-2-2010"

All OK

Then I create a read simply by dispatching on readPartialDate:

instance Read PartialDate where
         readsPrec _ s = case (readPartialDate s) of
                              Nothing -> []
                              Just p -> [(p, s)] 

Test code:

main = do
        [d] <- getArgs
        return $ show $ ((read d) :: PartialDate)
runHaskell PartialDate.hs 12-2-2010
PartialDate.hs: Prelude.read: no parse

Does anyone know why putting a working function into a read might give rise to a parse error?

readPartialDate uses Parsec, and also uses reverse, so might there be a laziness issue here?

Upvotes: 2

Views: 1185

Answers (1)

Daniel Fischer
Daniel Fischer

Reputation: 183873

The problem is that in the definition of readsPrec,

 readsPrec _ s = case (readPartialDate s) of
                      Nothing -> []
                      Just p -> [(p, s)] 

you give the input String itself as the second component of the readsPrec result pair. read requires that the reads result have the second component empty, meaning that the entire input has been consumed to determine the value (in general, when you write Read instances, make sure you don't forget to consume trailing whitespace). Change the instance to

 readsPrec _ s = case (readPartialDate s) of
                      Nothing -> []
                      Just p -> [(p, "")]

and it should work.

Upvotes: 4

Related Questions