
Hi Don:
This function is typically defined once per project. So its about time this safe variant of 'read' made it into the base.
maybeRead :: Read a => String -> Maybe a maybeRead s = case reads s of [(x, "")] -> Just x _ -> Nothing
Jeff:
Why not allow an arbitrary monad?
readM :: (Monad m, Read a) => String -> String -> m a readM errMsg s = case reads s of [(x, "")] -> return x _ -> fail errMsg
My instinct here is to follow James McKinna's observation (which give rise to views in Epigram): you don't need to produce elements of an *arbitrary* whatever-it-is when you can produce elements of the *initial* whatever-it-is. It makes the construction a bit easier to implement, because you're working at a concrete type, but no harder to use. I'd suggest going with the Maybe version, but then add the relevant initiality principles for Maybe (if they're not already there). This thing mayA :: Alternative a => Maybe x -> a x mayA (Just x) = pure x mayA Nothing = empty is a useful little piece of glue, and it has a few friends which might also help, including, for the moment, mayM :: Monadplus m => Maybe x -> m x mayM (Just x) = return x mayM Nothing = mzero and (oh all right then) mayhem :: Monad m => Maybe x -> m x mayhem (Just x) = return x mayhem Nothing = fail "I told you so!" These things are common factors in quite a lot of unnecessarily abstract operations. I suggest factoring out the final appeals to initiality, keeping the actual machinery simple and specific. All the best Conor