Why doesn't Haskell's Prelude.read return a Maybe?

ParsingHaskellTypes

Parsing Problem Overview


Is there a good reason why the type of Prelude.read is

read :: Read a => String -> a

rather than returning a Maybe value?

read :: Read a => String -> Maybe a

Since the string might fail to be parseable Haskell, wouldn't the latter be be more natural?

Or even an Either String a, where Left would contain the original string if it didn't parse, and Right the result if it did?

Edit:

I'm not trying to get others to write a corresponding wrapper for me. Just seeking reassurance that it's safe to do so.

Parsing Solutions


Solution 1 - Parsing

Edit: As of GHC 7.6, readMaybe is available in the Text.Read module in the base package, along with readEither: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v:readMaybe


Great question! The type of read itself isn't changing anytime soon because that would break lots of things. However, there should be a maybeRead function.

Why isn't there? The answer is "inertia". There was a discussion in '08 which got derailed by a discussion over "fail."

The good news is that folks were sufficiently convinced to start moving away from fail in the libraries. The bad news is that the proposal got lost in the shuffle. There should be such a function, although one is easy to write (and there are zillions of very similar versions floating around many codebases).

See also this discussion.

Personally, I use the version from the safe package.

Solution 2 - Parsing

Yeah, it would be handy with a read function that returns Maybe. You can make one yourself:

readMaybe :: (Read a) => String -> Maybe a
readMaybe s = case reads s of
              [(x, "")] -> Just x
              _ -> Nothing

Solution 3 - Parsing

Apart from inertia and/or changing insights, another reason might be that it's aesthetically pleasing to have a function that can act as a kind of inverse of show. That is, you want that read . show is the identity (for types which are an instance of Show and Read) and that show . read is the identity on the range of show (i.e. show . read . show == show)

Having a Maybe in the type of read breaks the symmetry with show :: a -> String.

Solution 4 - Parsing

As @augustss pointed out, you can make your own safe read function. However, his readMaybe isn't completely consistent with read, as it doesn't ignore whitespace at the end of a string. (I made this mistake once, I don't quite remember the context)

Looking at the definition of read in the Haskell 98 report, we can modify it to implement a readMaybe that is perfectly consistent with read, and this is not too inconvenient because all the functions it depends on are defined in the Prelude:

readMaybe        :: (Read a) => String -> Maybe a
readMaybe s      =  case [x | (x,t) <- reads s, ("","") <- lex t] of
                         [x] -> Just x
                         _   -> Nothing

Solution 5 - Parsing

This function (called readMaybe) is now in the Haskell prelude! (As of the current base -- 4.6)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBilal BarakatView Question on Stackoverflow
Solution 1 - ParsingsclvView Answer on Stackoverflow
Solution 2 - ParsingaugustssView Answer on Stackoverflow
Solution 3 - Parsingyatima2975View Answer on Stackoverflow
Solution 4 - ParsinglpsmithView Answer on Stackoverflow
Solution 5 - ParsingamindfvView Answer on Stackoverflow