2011-11-09 41 views
95

有一個很好的理由Prelude.read的類型是爲什麼Haskell的Prelude.read不會返回Maybe?

read :: Read a => String -> a 

,而不是返回一個Maybe價值?

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

由於字符串可能無法被解析的哈斯克爾,不會後者可以更自然?

甚至Either String a,其中Left將包含原始字符串,如果它不解析,並且Right結果如果它?

編輯:

我不想讓別人寫一個相應的包裝我。只是爲了保證這樣做是安全的。

+12

爲什麼'take'不接受任何'Num a => a'?爲什麼列表中有'fmap'的特殊情況?爲什麼'Monad'實例不需要'Functor'?我希望答案與這些和相關問題的答案類似。 – delnan

+3

那麼,這就是爲什麼我按照我的方式措辭,讓選項開放,沒有什麼好的理由。雖然我也懷疑可能沒有像您提供的衆所周知的示例一樣,但值得一提的是確保編寫我自己的包裝不會在下游創建不可預見的問題。 –

+0

我希望很快會添加'readMaybe'函數。 – augustss

回答

93

編輯:作爲GHC 7.6,readMaybe是在基地Text.Read庫提供,readEither一起:http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v:readMaybe


大問題!閱讀本身的類型不會很快改變,因爲這會破壞很多東西。不過,應該maybeRead函數。

爲什麼不存在?答案是「慣性」。有一個discussion in '08由於「失敗」的討論而脫軌。

好消息是,人們有足夠的信心開始擺脫圖書館的失敗。壞消息是這項提案在混亂中迷失了方向。有應該是這樣一個功能,雖然一個很容易寫(並且有很多非常相似的版本漂浮在許多代碼庫周圍)。請參閱this discussion

就我個人而言,我使用safe package的版本。

26

是的,這將是一個方便的閱讀函數返回Maybe。你可以自己做一個:

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

謝謝!我希望編輯不會忘恩負義! :)只是想說清楚我並不是要求懶惰...... –

+6

如果@augustss無法提供它,更好的答案可能不存在。 –

+2

我不認爲可能的版本曾經在原始設計中討論過。許多這些事情隨着經驗而變得明顯,但很難預測。 – augustss

14

除了慣性和/或改變的見解,另一個原因可能是,它的美觀有可以作爲一種show逆的行爲的功能。也就是說,你希望那read . show是標識(這是ShowRead一個實例類型)和show . read是對show(即show . read . show == show

read斷類型有一個Maybe範圍身份與show :: a -> String對稱。

+0

感謝您添加一個新角度!這就說得通了。但是爲了達到這個目的,如果顯示和閱讀產生不同的類型,比如說「ParseableString」,是不是有意義? –

+1

@BilalBarakat:不同的類型可能是'newtype ValidShow a = ValidShow String'。幻影類型使它更安全。 – yairchu

+7

這是一個有趣的觀點,但最終卻是一種錯誤的對稱。程序員應該重視美學的正確性。 –

11

正如@augustss指出的那樣,您可以使自己的安全閱讀功能。但是,他的readMaybe與read不完全一致,因爲它不會忽略字符串末尾的空格。(我犯了這個錯誤一次,我不太記得上下文)

望着definition of read in the Haskell 98 report,我們可以修改它來實現一個readMaybe是與read完全一致,這是不是太不方便了,因爲所有的功能這取決於在前奏中定義:

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',它和這個版本是一樣的 –

6

此功能(稱爲readMaybe)現在在Haskell的序幕! (截至目前的基數 - 4.6)

+2

嗯,鏈接文本說它是在Text.Read中而不是在前奏(可能已經改變),但是,它仍然幫助我! – Kapichu

相關問題