Почему 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)