The most common way is to just auto derive Read. I'm not sure that that ever really fails. Are you sure the problem isn't with the Show instance of the type? People commonly write invalid Show instances to make them look pretty and they shouldn't. read and show are supposed to be inverses of each other because when they aren't, problems like this occur.
The simple way to do a Read instance is to implement the reads function for it. The confusion comes from its type. readsPrec :: Int -> ReadS a. ReadS is defined as String -> [(a, String)], where a is the parsed result and String is the rest of the string that is being parsed, , which may look confusing, and the Int is precedence, which can usually be ignored. It could have been Int -> String -> Maybe (a, String), but Read predates Maybe. So instead it returns a list and if it fails to parse, it returns [] instead of Nothing. So.
data MyFoo = MyFoo
instance Read MyFoo where
-- readsPrec :: Int -> String -> [(MyFoo, String)]
readsPrec _ = readFoo
readFoo :: String -> [(MyFoo, String)]
readFoo str = case splitAt 5 str of
("MyFoo", rest) -> [(MyFoo, rest)]
otherwise -> []
But honestly I think you should look at fixing your Show instance first, if possible.