Why does this Read instance parse inconsistently?
import qualified Data.List as List
data Foo = Foo
instance Show Foo where
show _ = "Foo"
instance Read Foo where
readsPrec _ s = case List.stripPrefix "Foo" s of
Just rest -> [(Foo, rest)]
Nothing -> []
This is expected:
Test> reads "" :: [(Foo, String)]
[]
This is unexpected:
Test> read "" :: Foo
Foo
I would expect it to throw.
CodePudding user response:
The problem isn't in read
, but in show
. Your show
implementation doesn't force the input value of type Foo
, because it returns "Foo"
unconditionally, without even matching a constructor. If you use the derived Show
instance, or write its equivalent by hand:
instance Show Foo where
show Foo = "Foo"
then you will get the expected error when you try to parse a malformed string, because evaluating show
will actually require parsing the input string.