Haskell의 Prelude.read가 Maybe를 반환하지 않는 이유는 무엇입니까?


108

Prelude.read 유형이 좋은 이유가 있습니까?

read :: Read a => String -> a

Maybe값을 반환하는 대신 ?

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

문자열이 Haskell을 구문 분석하지 못할 수 있으므로 후자가 더 자연스럽지 않을까요?

또는 Either String a, Left파싱하지 않으면 원래 문자열을 포함하고 Right그 결과를 포함하면 어디에 있습니까?

편집하다:

나는 다른 사람들이 나를 위해 상응하는 래퍼를 작성하도록하려는 것이 아닙니다. 그렇게하는 것이 안전하다는 확신을 구하는 것뿐입니다.


14
왜 아무것도 take받아들이지 Num a => a않습니까? fmapfor 목록에 특별한 경우가있는 이유는 무엇 입니까? 인스턴스에 왜 Functor필요하지 Monad않습니까? 이 질문 및 관련 질문에 대한 답변과 유사 할 것으로 예상합니다.

3
글쎄, 그게 내가했던 방식으로 표현한 이유이며, 좋은 이유가 없다는 옵션을 열어 두었습니다. 나는 또한 당신이 제공하는 잘 알려진 예와 같이 없을 수도 있다고 생각하지만, 내 자신의 래퍼를 작성하는 것이 예상치 못한 문제를 하류로 만들지 않도록 요청하는 것이 좋습니다.
Bilal Barakat

readMaybe곧 기능이 추가 되기를 바랍니다 .
8

좋은 점은 @delnan하지만,하지 말아야 takeIntegral n => n -> [a] -> [a]?
Doug McClean 2011

@DougMcClean : 예, 실제로 뇌 방귀가 Integral아닌 이어야합니다 Num.

답변:


106

편집 : GHC 7.6로, readMaybe에서 사용할 수 Text.Read와 함께, 기본 패키지 모듈 readEither: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v : readMaybe


좋은 질문입니다! 읽기 자체의 유형은 많은 것을 깨뜨릴 것이기 때문에 조만간 변경되지 않습니다. 그러나 기능 이 있어야 합니다 maybeRead.

왜 거기에 없습니까? 대답은 "관성"입니다. 이 있었다 '08 토론 을 통해 토론에 의해 탈선되었다 "실패는."

좋은 소식은 사람들이 도서관에서 실패에서 벗어나기 시작할만큼 충분히 확신했다는 것입니다. 나쁜 소식은 제안이 셔플에서 길을 잃었다는 것입니다. 하나는 작성하기 쉽지만 그러한 함수 가 있어야 합니다 (많은 코드베이스 주위에 매우 유사한 버전이 무수히 많이 있습니다).

이 토론을 참조하십시오 .

개인적으로 안전한 패키지 의 버전을 사용합니다 .


30

예, Maybe를 반환하는 읽기 함수를 사용하면 편리합니다. 직접 만들 수 있습니다.

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

3
감사합니다! 편집이 배은망덕하지 않기를 바랍니다! :) 그냥 내가 게으름에서 요구하지 않는다는 것을 분명히하고 싶다 ...
Bilal Barakat

6
@augustss가 제공 할 수없는 경우 더 나은 답변이 없을 수 있습니다.
John L

2
원래 디자인에서 아마도 버전이 논의 된 적이 없다고 생각합니다. 이러한 많은 것들은 경험을 통해 분명해 지지만 예측하기 어려울 수 있습니다.
8

이유 목록 수익률을 읽고 여러 개의 유효 파싱 존재하는 경우입니다. Maybe 케이스는 읽기와 읽기 사이의 중간입니다.
Chris Kuklewicz 2011

나는이 필요 생각 Read atypeclass을 :readMaybe :: Read a => String -> Maybe a
데이비드 Tchepak

15

관성 및 / 또는 변화하는 통찰력을 제외하고, 또 다른 이유는 show. 즉, 그것이 read . showID ( Show및 인스턴스 인 유형의 경우 Read)이고 show . read범위의 ID 인 show(즉 show . read . show == show)

Maybe유형에 a 가 있으면 read와의 대칭 이 끊어집니다 show :: a -> String.


새로운 각도를 추가해 주셔서 감사합니다! 말이 되네요. 그러나이를 명확하게 달성하기 위해 "ParseableString"과 같이 표시 및 읽기가 서로 다른 유형을 생성하는 것이 합리적이지 않습니까?
Bilal Barakat 2011

1
@BilalBarakat : 구별 유형은 newtype ValidShow a = ValidShow String. 팬텀 유형은 더 유형 안전합니다.
yairchu

9
흥미로운 점이지만 궁극적으로 잘못된 대칭입니다. 프로그래머는 미학보다 정확성을 중요시해야합니다.
Matt Fenwick

1
@yairchu 팬텀 유형에 대해 당신이 의미하는 바가 즉시 명확하지 않았으므로 다른 사람이 저처럼 혼란 스러울 경우를 대비하여 명확히하겠습니다. 당신은 같은 의도 showThing :: Show a => a -> ValidShow areadThing :: Read a => ValidShow a -> a보여 줬던 물건의 종류가 ValidShow 객체에 기억되고 그래서. 이렇게하면 readThing (showThing True) :: String.
amalloy

12

@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

1
감사! +1은 이전에 명시되지 않은 공백 문제를 알려줍니다.
Bilal Barakat 2011

3
safe패키지 만 사용하는 경우 사용 readMaybe가능한 올바른 버전을 얻을 수 있습니다 ( readMay이 버전과 동일하며 호출 됩니다.
Neil Mitchell

8

이 함수 (라고 함 readMaybe)는 이제 Haskell 전주곡에 있습니다! (현재 기준-4.6)


2
글쎄, 링크 된 텍스트는 Prelude가 아니라 Text.Read에 있다고 말합니다 (변경되었을 수 있음).하지만 여전히 도움이되었습니다!
Kapichu 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.