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 => afmapforリストの特別なケースがあるのはなぜですか?インスタンスになぜFunctor必要ないのですMonadか?私の答えは、これらの質問や関連する質問の答えと似ていると思います。

3
まあ、それが私が私がしたようにそれを表現した理由であり、正当な理由がないという選択肢を開いたままにします。私はまた、あなたが与える有名な例のように、ないかもしれないと思いますが、私自身のラッパーを書くことが予期しない問題を下流で作成しないことを確認することを確認することは価値があります。
ビラルバラカット

readMaybeすぐに機能が追加されることを期待しています。
8

@delnanの良い点ですが、そうすべきではありませtakeIntegral n => n -> [a] -> [a]か?
Doug McClean

@DougMcClean:はい、それは実際にはIntegralNum脳のオナラではない- であるべきです。

回答:


106

編集:GHC 7.6以降、次のパッケージとともに、基本パッケージのモジュールでreadMaybe利用可能です:http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v:たぶんText.ReadreadEither


すばらしい質問です。読み取り自体の種類は、多くのことを壊すため、すぐに変わることはありません。しかし、そこになければならないことmaybeReadの機能。

なぜそこにないのですか?答えは「慣性」です。「失敗」をめぐる議論によって混乱した2008年の議論がありました。

良い知らせは、人々は図書館で失敗から脱却し始めるのに十分確信しているということです。悪いニュースは、提案がシャッフルで失われたことです。そのような関数はあるはずですが、書くのは簡単です(そして、非常によく似たバージョンが無数にあり、多くのコードベースに浮かんでいます)。

この議論も参照してください。

個人的には、安全なパッケージのバージョンを使用しています


30

ええ、それは多分多分を返す読み取り関数で便利でしょう。あなたは自分で作ることができます:

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

3
ありがとうございました!編集が恩知らずに聞こえないことを願っています!:)明確にしたいのですが、私は怠惰を求めているわけではありません...
ビラルバラカット

6
@augustssがそれを提供できない場合、より良い答えは存在しない可能性があります。
John L

2
多分バージョンがオリジナルのデザインで議論されたことはないと思います。これらの多くは経験とともに明らかになりますが、予測するのは難しい場合があります。
8

その理由のリストを返すを読み込み、複数の有効なパースがある場合です。多分ケースは読み取りと読み取りの中間です。
Chris Kuklewicz

これにはRead atypeclass が必要だと思います:readMaybe :: Read a => String -> Maybe a
David Tchepak 2012

15

慣性や洞察の変化とは別に、もう1つの理由は、の一種の逆関数として機能する機能があることは、見た目が楽しいことですshow。つまり、それがread . showShowおよびのインスタンスである型のReadshow . readIDであり、それがshow(つまりshow . read . show == show)の範囲のIDであることが必要です。

持つMaybeの種類にread休憩と対称性show :: a -> String


新しい角度を追加してくれてありがとう!それは理にかなっている。しかし、それをきれいに実現するために、 "ParseableString"のように、表示と読み取りの両方で異なる型を生成することは意味がないのではないでしょうか。
ビラルバラカット

1
@BilalBarakat:特殊タイプはである可能性がありますnewtype ValidShow a = ValidShow String。ファントムタイプを使用すると、タイプセーフになります。
yairchu

9
それは興味深い点ですが、結局のところ、誤った対称性です。プログラマーは美学よりも正確さを重視するべきです。
Matt Fenwick

1
@yairchuファントムタイプについてあなたが何を言っているのかすぐにはわからなかったので、他の誰かが私のように混乱している場合に備えて明確にします。showThing :: Show a => a -> ValidShow aandのようなものを意図しているreadThing :: Read a => ValidShow a -> aので、表示されたもののタイプはValidShowオブジェクトに記憶されます。このように書くことはできませんreadThing (showThing True) :: String
アマロイ2018年

12

@augustssが指摘したように、独自の安全な読み取り関数を作成できます。ただし、readMaybe文字列の末尾の空白を無視しないため、読み取りと完全には一致していません。(私は一度この間違いをしました、私はコンテキストを完全に覚えていません)

Haskell 98レポートのread定義を見て、readMaybeと完全に一致するaを実装するように変更でき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は、以前は明示されていなかった空白の問題について私に警告するためのものです。
ビラルバラカット

3
あなただけ使用する場合は、その注意safeパッケージを、あなたは正しいバージョンの取得readMaybe(それを呼び出して利用できreadMay、それは、このバージョンと同じだが。
ニール・ミッチェル

8

この関数(と呼ばれますreadMaybe)がHaskellプレリュードに登場しました!(現在のベース-4.6)


2
まあ、リンクされたテキストは、それがText.Readにあり、Preludeにはない(変更されている可能性があります)とありますが、それでも私には役立ちました!
カピチュ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.