Почему Haskell Prelude.read не возвращает Maybe?

Есть ли веская причина, почему тип Prelude.read

read :: Read a => String -> a

вместо того, чтобы возвращать значение Maybe?

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

Поскольку строка может не обрабатываться Haskell, не будет ли последнее более естественным?

Или даже Either String a, где Left будет содержать исходную строку, если она не анализируется, и Right результат, если он сделал?

Edit:

Я не пытаюсь заставить других писать соответствующую оболочку для меня. Просто добивайтесь уверенности в том, что это безопасно.

Ответ 1

Изменить: Начиная с GHC 7.6, readMaybe доступен в модуле Text.Read в базовом пакете вместе с readEither: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html # v: readMaybe


Отличный вопрос! Тип чтения сам по себе не изменится в ближайшее время, потому что это сломает много вещей. Тем не менее, должна быть функция maybeRead.

Почему там нет? Ответ "инерция". В 2008 году была дискуссия, которая была сорвана из-за обсуждения "провал".

Хорошей новостью является то, что люди были достаточно убеждены, чтобы начать отказываться от неудач в библиотеках. Плохая новость заключается в том, что предложение потеряно в случайном порядке. Должна быть такая функция, хотя ее легко написать (а вокруг многих баз кода плавают миллионы очень похожих версий).

Смотрите также это обсуждение.

Лично я использую версию из безопасного пакета.

Ответ 2

Да, это было бы удобно с функцией чтения, которая возвращает Maybe. Вы можете сделать это самостоятельно:

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

Ответ 3

Помимо инерции и/или изменения взглядов, другая причина может заключаться в том, что эстетически приятно иметь функцию, которая может действовать как своего рода инверсия show. То есть вы хотите, чтобы read . show являлся идентификатором (для типов, являющихся экземпляром show и Read), и что show . read является идентификатором в диапазоне show (т.е. show . read . show == show)

Наличие a Maybe в типе Read нарушает симметрию с show :: a -> String.

Ответ 4

Как отметил @augustss, вы можете сделать свою собственную функцию безопасного чтения. Однако его readMaybe не полностью согласуется с чтением, так как он не игнорирует пробелы в конце строки. (Однажды я сделал эту ошибку, я не совсем помню контекст)

Глядя на определение чтения в отчете Haskell 98, мы можем изменить его для реализации readMaybe, который идеально согласуется с read, и это не слишком неудобно, потому что все функции, от которых он зависит, определены в Prelude:

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

Ответ 5

Эта функция (называемая readMaybe) теперь находится в прелюдии Haskell! (Начиная с текущей базы - 4.6)