
Dan Doel wrote:
readEither s = case [ x | (x,"") <- readPrec_to_S read' minPrec s ] of [x] -> Right x [] -> Left "Prelude.read: no parse" _ -> Left "Prelude.read: ambiguous parse"
Because there are multiple error cases, I support the Monad version. I agree with everyone who has said that fail is a wart, but since we don't have a haskell98 'MonadStringError', and 'MonadError' requires fundeps and MPTCs, I think fail is the best we have at the moment. If we were prepared to endorse fundeps and MPTCs then I might support a (Error e, MonadError e m,Read a) => String -> m a type. If there was only one error case, then Maybe would contain enough information, and I would support the simpler version. As there are three (no parse, ambiguous parse, and incomplete parse), it is losing information just to product Nothing. +1 for Text.Read.readM from me. Dan points out in conversation that a MonadPlus constraint might be considered a 'valid hint' that fail is a sensible operation. Without wishing to derail the conversation, common combinators to promote and demote error types might be good thigns to document and possibly even include in the standard lib. One example which springs to mind is maybe (fail "it went wrong") return which the combinator to "promote" from unlabelled errors (Maybe) to labelled errors (presumably in an error monad). Or with a custom error type, something like maybe (throwError ThereWasAProblem) return which could be set up as an infix like this: possiblyFailingOperation `withError` ThereWasAProblem There are a whole bunch of tricks like this for embedding one error strategy inside another which are 'obvious' and even 'folklore' but not written down. Jules