2015-05-03 20 views
1

所以我剛剛遇到了ghci如下:哈斯克爾ghci中讀取*行爲和最大

(*) (read "10") (read "20") 

收益200如預期。不過,此行

(max) (read "10") (read "20") 

拋出異常:

*** Exception: Prelude.read: no parse 

而且我真的不能找出這樣的ghci的行爲的原因。任何幫助,將不勝感激!

回答

7

這是GHCi違約規則的一個實例。當遇到不明確的類型時,它會選擇()(「unit」)作爲默認值。所以它試圖讀取10作爲()類型的值,該值無法解析。

的類型不明確,因爲read的返回類型超載對Read任何情況下工作,並max的參數類型超載對Ord任何情況下工作,所以編譯器沒有任何辦法知道哪種你打算爲中間值:

read :: (Read a) => String -> a 
max :: (Ord a) => a -> a -> a 

您還將看到此行爲如果你只是寫:

read "10" 

但是寫這將工作:

read "()" 

一種解決方案是給一個明確的類型註釋:

max (read "10" :: Int) (read "20" :: Int) 

這將返回20預期。

你也可以用命令行標誌,禁用此行爲:

ghci -XNoExtendedDefaultRules 

或者用GHCI命令:

:set -XNoExtendedDefaultRules 

,然後你會得到的線沿線的一個相應的錯誤信息「沒有Ord a0 ...的實例...類型變量a0不明確」。

+1

事實上,一個':: Int'就足夠了。 – Adrian

+0

@ addy2012:的確如此,但在這種情況下,我更願意明確並避免依賴推理。例如,我通常更喜歡寫'[a,b,c] :: [Int]'而不是'[a :: Int,b,c]',儘管它有點多餘。 –